MySQL学习41条

MySQL学习41条

1. database
a. SHOW DATABASES;
b. CREATE DATABASE test;
c. SHOW CREATE DATABASE;
d. SHOW STATUS;

2. column
a. SELECT colname1, colname2 FROM tablename;
b. SELECT DISTINCT vend_id FROM products;
c. DESCRIBE tablename; == SHOW COLUMNS FROM tablename;

3. 只返回部分结果
a. SELECT prod_name FROM products LIMITS 5; 开始5行
b. SELECT prod_name FROM products LIMITS 5,5; 次5行

4. 对返回的结果进行排序: 可通过非选择列进行排序; 也可按照多列进行排序
a. SELECT prod_name FROM products ORDER BY vend_id;
b. SELECT prod_name FROM products ORDER BY vend_id, prod_name;

5. 找出某列中价格最高,最低的产品
a. SELECT prod_price FROM products ORDER BY prod_price DESC LIMIT 1; 最高
b. SELECT prod_price FROM products ORDER BY prod_price LIMIT 1; 最低

6. WHERE操作符:= <> != < <= > >= BETWEEN
a. SELECT prod_price FROM products WHERE prod_name = ‘Fuses’; 字符比较不区分大小写
b. SELECT prod_price FROM products WHERE prod_price BETWEEN 5 AND 10;
c. SELECT prod_price FROM products WHERE prod_price IS NULL; 空值检查,没有设价格不等于价格为0

7. IN操作符等同于OR,但是更简洁些;NOT操作符取反
a. SELECT vend_id, prod_id, prod_price FROM products WHERE vend_id IN (1002,1003);
b. SELECT vend_id, prod_id, prod_price FROM products WHERE vend_id = 1002 OR vend_id = 1003;
c. SELECT vend_id, prod_id, prod_price FROM products WHERE vend_id NOT IN (1002,1003);

8. %通配符,表示任意字符出现的任意次数;_只匹配单个字符
a. SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name LIKE ‘%anvil%’;
b. SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name LIKE ‘Saf_’;

9. REGEXP是MySQL实现的部分正则功能;LIKE需要与通配符结合才可以,REGEXP则不需要
a. SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name LIKE ‘Saf_’;
b. SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP ‘Saf.’;

10. REGEXP正则匹配不区分大小写,使用BINARY可开启区分大小写模式
a. SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP BINARY ‘Saf.’;
b. SELECT vend_id, prod_id, prod_name FROM products WHERE vend_id REGEXP ‘1001|1002’;
c. SELECT vend_id, prod_id, prod_name FROM products WHERE vend_id IN (1001,1002);

11. 通过[]中的字符来匹配某几个字符之一
a. SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP BINARY ‘[123] ton’;
b. SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP BINARY ‘[1|2|3] ton’;

12. RGEEXP支持自定义字符集,称为字符类(characterclass)
a. [:alnum:]=[a-zA-Z0-9] [:lower:] = [a-z] [:upper:] = [A-Z]
b. [:alpha:] = [a-zA-Z]
c. [:digit:] = [0-9]
d. [:xdigit] = [a-fA-F0-9]

13. 重复元字符匹配
a. * (>=0)
b. + (>=1)
c. ? (0 or 1)
d. {n} (=n)
e. {n,} (>=n)

f. {n,m} (n<=x<=m)

SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP ‘\([0-9] sticks?\)’;
+———+———+—————-+
| vend_id | prod_id | prod_name |
+———+———+—————-+
| 1003 | TNT1 | TNT (1 stick) |
| 1003 | TNT2 | TNT (5 sticks) |
+———+———+—————-+
2 rows in set (0.00 sec)
SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP ‘[[:digit:]]{4}’;
+———+———+————–+
| vend_id | prod_id | prod_name |
+———+———+————–+
| 1005 | JP1000 | JetPack 1000 |
| 1005 | JP2000 | JetPack 2000 |
+———+———+————–+
2 rows in set (0.00 sec)


14. 定位符
a. ^在集合内部表示否定该集合,在外表示文本的开始
b. $表示文本的结尾, [[: 表示词的开始, [[:>:]]词的结尾
SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP ‘^[[:digit:]\.]’;
SELECT vend_id, prod_id, prod_name FROM products WHERE prod_name REGEXP ‘^[0-9\.]’;

15. MySQL正则表达式测试
:a. 不适用数据库的情况下简单测试正则表达式是否正确

mysql> SELECT ‘abc123’ REGEXP ‘[0-9]’;
+————————-+
| ‘abc123’ REGEXP ‘[0-9]’ |
+————————-+
| 1 |
+————————-+
1 row in set (0.00 sec)
mysql> SELECT ‘abc’ REGEXP ‘[0-9]’;
+———————-+
| ‘abc’ REGEXP ‘[0-9]’ |
+———————-+
| 0 |
+———————-+
1 row in set (0.00 sec)


16. 计算字段
a. 字段(field)与列(column)意思基本相同
b. 计算字段是根据存储在表中的数据转换、格式化后可供客户端直接使用的数据
c. 计算字段不实际存在于数据库表中,计算字段是在运行时由SELECT语句创建的

17. 字段拼接
a. 拼接(concatenate)是指将值联接到一起构成单个值

mysql> SELECT Concat(vend_name, ’ (‘,vend_country, ‘)’) FROM vendors ORDER BY vend_name;
+——————————————-+
| Concat(vend_name, ’ (‘,vend_country, ‘)’) |
+——————————————-+
| ACME (USA) |
| Anvils R Us (USA) |
| Furball Inc. (USA) |
| Jet Set (England) |
| Jouets Et Ours (France) |
| LT Supplies (USA) |
+——————————————-+
6 rows in set (0.02 sec)


18. 字段别名
a. 一个字段或值得替换名叫做别名(alias)
mysql> SELECT Concat(Rtrim(vend_name), ’ (‘,vend_country, ‘)’) AS vend_title FROM vendors ORDER BY vend_name;
mysql> SELECT prod_id, quantity, item_price, quantity*item_price AS expanded_price FROM orderitems WHERE order_num = 20005;
+———+———-+————+—————-+
| prod_id | quantity | item_price | expanded_price |
+———+———-+————+—————-+
| ANV01 | 10 | 5.99 | 59.90 |
| ANV02 | 3 | 9.99 | 29.97 |
| TNT2 | 5 | 10.00 | 50.00 |
| FB | 1 | 10.00 | 10.00 |
+———+———-+————+—————-+
4 rows in set (0.01 sec)

19. SQL自带函数
a. 文本函数(RTrim/LTrim/Soundex/Upper/SubString/Left/Right)
b. 数值函数 (Abs/Cos/Exp/Mod/Pi/Rand/Sin/Sqrt/Tan)
c. 日期时间函数(Year/Month/Day/Hour/Date/Time/DayOfWeek)
mysql> SELECT cust_id, order_num FROM orders WHERE Date(order_date)
mysql> SELECT cust_id, order_num FROM orders WHERE Year(order_date) = 2005 AND Month(order_date) = 9;

20. 聚集函数(aggregate function)运行在行组上,用于汇总数据
a. 相关函数(AVG/COUNT/MAX/MIN/SUM)
mysql> SELECT AVG(prod_price) AS avg_price FROM products;
mysql> SELECT AVG(DISTINCT prod_price) AS avg_price FROM products;
mysql> SELECT MIN(prod_price) AS avg_price FROM products;
mysql> SELECT MAX(prod_price) AS avg_price FROM products;
mysql> SELECT COUNT(*) AS num_cust FROM customers;
mysql> SELECT * FROM customers;
+———+—————-+———————+———–+————+———-+————–+————–+———————+
| cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email |
+———+—————-+———————+———–+————+———-+————–+————–+———————+
| 10001 | Coyote Inc. | 200 Maple Lane | Detroit | MI | 44444 | USA | Y Lee | [email protected] |
| 10002 | Mouse House | 333 Fromage Lane | Columbus | OH | 43333 | USA | Jerry Mouse | NULL |
| 10003 | Wascals | 1 Sunny Place | Muncie | IN | 42222 | USA | Jim Jones | [email protected] |
| 10004 | Yosemite Place | 829 Riverside Drive | Phoenix | AZ | 88888 | USA | Y Sam | [email protected] |
| 10005 | E Fudd | 4545 53rd Street | Chicago | IL | 54545 | USA | E Fudd | NULL |
+———+—————-+———————+———–+————+———-+————–+————–+———————+
5 rows in set (0.00 sec)
mysql> SELECT COUNT(cust_id) AS num_cust FROM customers;
+———-+
| num_cust |
+———-+
| 5 |
+———-+
1 row in set (0.00 sec)
mysql> SELECT COUNT(cust_email) AS num_cust FROM customers;
+———-+
| num_cust |
+———-+
| 3 |
+———-+
1 row in set (0.00 sec)

21. 分组
a. 分组把数据分为多个逻辑组,方便对每个组进行聚集运算
mysql> SELECT vend_id, COUNT(*) AS num_prods FROM products GROUP BY vend_id;
mysql> SELECT vend_id, COUNT(*) AS num_prods FROM products GROUP BY vend_id WITH ROLLUP; // 最后一行为各个分组num_prods之和,即为总产品信息
b. WHERE 基于行进行过滤,HAVING 是基于分组进行过滤的
SELECT vend_id, COUNT( ) AS num_prods FROM products GROUP BY vend_id HAVING COUNT() >= 3;
c. GROUP BY 分组行,但输出不一定是分组的顺序,必须提供ORDER BY子句进行分组
mysql> SELECT order_num, SUM(quantity*item_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING ordertotal >= 50 ORDER BY ordertotal;

22. SELECT语句中关键字出现顺序
a. SELECT > FROM > WHERE > GROUP BY > HAVING > ORDER BY > LIMIT

23. 子查询(subquery):即嵌套在其他查询中的查询
a. 子查询总是由内向外处理
SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = ‘TNT2’);
b. 从customers表中检索客户列表,从order表中统计每个客户的订单总数
SELECT cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;

24. 联接(join)
a. 主键(primary key):能够唯一表示数据表中的每个记录的字段或者字段的组合就称为主键
b. 外键 (foreign key):外键为某个表中的一列,它包含了另一个表的主键值
c. 联接:联接是一种机制,用来在一条SELECT语句中关联表;
d. WHERE子句可作为过滤条件,在联接时输出匹配给定条件(联接条件)的行
SELECT vend_name, prod_name, prod_price FROM vendors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name;
e. 笛卡尔积(cartesianproduct): 由没有联接条件的表关系返回的结果称为笛卡尔积;又称为叉联接(cross join),或叉乘(Product)

25. 内部联接(join)
a. 基于两个表之间的相等测试进行的联接成为 等值联接(equijoin),也叫 内部联接(inner join); 笛卡尔积就是典型的内部联接(所有相等条件为真)
b. 上面用WHERE语句的内部联接也可以写为:
SELECT vend_name, prod_name, prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name;

26. 自联接(selfjoin)
a. 自联接(selfjoin)就是和自身联接
b. 如发现某物品(其ID为DTNTR)有质量问题,想找到生产该物品的供应商生产的其它物品,检查质量;使用自联接或WHERE的方式分别为:
SELECT prod_id, prod_name FROM products WHERE vend_id = (SELECT vend_id FROM products WHERE prod_id = ‘DTNTR’);
SELECT p1.prod_id, p1.prod_name FROM products AS p1, products AS p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = ‘DTNTR’;

27. 自然联接(nature join)
a. 自然联接是内部联接的特殊形式;内部联接返回数据中相同的列多次出现均会返回;自然联接排除多次出现,使每个列只返回一次
b. 自然联接的实现有用户手动实现,一般通过对当前表使用通配符(SELECT*),对其它表使用明确的子集完成
SELECT * FROM vendors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name LIMIT 1;
+———+———–+—————–+————-+————+———-+————–+———+———+———–+————+—————————————+
| vend_id | vend_name | vend_address | vend_city | vend_state | vend_zip | vend_country | prod_id | vend_id | prod_name | prod_price | prod_desc |
+———+———–+—————–+————-+————+———-+————–+———+———+———–+————+—————————————+
| 1003 | ACME | 555 High Street | Los Angeles | CA | 90046 | USA | FB | 1003 | Bird seed | 10.00 | Large bag (suitable for road runners) |
+———+———–+—————–+————-+————+———-+————–+———+———+———–+————+—————————————+
1 row in set (0.03 sec) // 内部联接
mysql> SELECT v.*, p.prod_name FROM vendors AS v, products AS p WHERE v.vend_id = p.vend_id ORDER BY vend_name, prod_name LIMIT 1;
+———+———–+—————–+————-+————+———-+————–+———–+
| vend_id | vend_name | vend_address | vend_city | vend_state | vend_zip | vend_country | prod_name |
+———+———–+—————–+————-+————+———-+————–+———–+
| 1003 | ACME | 555 High Street | Los Angeles | CA | 90046 | USA | Bird seed |
+———+———–+—————–+————-+————+———-+————–+———–+
1 row in set (0.02 sec) // 自然联接

28. 外部联接(out join)
a. 联接包含了那些在相关表中没有关联行的行,这种联接称为外部联接; 内部联接只包含相关行
mysql> SELECT c.cust_id, o.order_num FROM customers AS c INNER JOIN orders AS o ON c.cust_id = o.cust_id;
+———+———–+
| cust_id | order_num |
+———+———–+
| 10001 | 20005 |
| 10001 | 20009 |
| 10003 | 20006 |
| 10004 | 20007 |
| 10005 | 20008 |
+———+———–+
5 rows in set (0.03 sec) // 内部联接
mysql> SELECT c.cust_id, o.order_num FROM customers AS c LEFT OUTER JOIN orders AS o ON c.cust_id = o.cust_id;
+———+———–+
| cust_id | order_num |
+———+———–+
| 10001 | 20005 |
| 10001 | 20009 |
| 10002 | NULL |
| 10003 | 20006 |
| 10004 | 20007 |
| 10005 | 20008 |
+———+———–+
6 rows in set (0.00 sec) // 外部联接
mysql> SELECT c.cust_name, c.cust_id, COUNT(o.order_num) FROM customers AS c INNER JOIN orders AS o ON c.cust_id = o.cust_id GROUP BY c.cust_id;
+—————-+———+——————–+
| cust_name | cust_id | COUNT(o.order_num) |
+—————-+———+——————–+
| Coyote Inc. | 10001 | 2 |
| Wascals | 10003 | 1 |
| Yosemite Place | 10004 | 1 |
| E Fudd | 10005 | 1 |
+—————-+———+——————–+
4 rows in set (0.00 sec) // 带聚集函数的内部联接
mysql> SELECT c.cust_name, c.cust_id, COUNT(o.order_num) FROM customers AS c LEFT OUTER JOIN orders AS o ON c.cust_id = o.cust_id GROUP BY c.cust_id;
+—————-+———+——————–+
| cust_name | cust_id | COUNT(o.order_num) |
+—————-+———+——————–+
| Coyote Inc. | 10001 | 2 |
| Mouse House | 10002 | 0 |
| Wascals | 10003 | 1 |
| Yosemite Place | 10004 | 1 |
| E Fudd | 10005 | 1 |
+—————-+———+——————–+
5 rows in set (0.00 sec) // // 带聚集函数的外部联接

29. 组合查询(union/compoundquery)
a. MySQL允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果返回;这样的查询称为组合查询,或复合查询(union/compoundquery)
b. 查询价格小于5的所有物品的列表,并且包括供应商1001和1002生产的所有物品(不考虑价格)
SELECT vend_id, prod_id, prod_price FROM products WHERE prod_price <= 5 OR vend_id IN (1001, 1002);
SELECT vend_id, prod_id, prod_price FROM products WHERE prod_price <= 5 UNION SELECT vend_id, prod_id, prod_price FROM products WHERE vend_id IN (1001, 1002);
c. UNION使用时各个SELECT对应的列名必须对应相等;如果使用表达式或聚集函数,也必须一样;UNION默认消除重复行,使用UNION ALL可以保留重复行;UNION中排序语句ORDER BY只可放在最后一条SELECT语句后,但它对所有SELECT语句返回的行起作用

30. 全文本搜索
a. 为了对表进行全文本搜索,必须在创建表时通过FULLTEXT子句指定索引列。
b. 进行全文本搜索使用Match()和Against();其中Match 指定被搜索的列,Against()指定要使用的搜索表达式。
SELECT note_text FROM productnotes WHERE Match(note_text) Against(‘rabbit’);
SELECT note_text FROM productnotes WHERE note_text LIKE ‘%rabbit%’; 等价于上行,但上面语句输出将结果按照文本的匹配程度排序
SELECT note_text, Match(note_text) Against(‘rabbit’) AS rank FROM productnotes; 列rank显示匹配程度数值
c. 使用查询扩展返回扩展结果:第一轮使用全文本搜索,找出匹配行;第二轮从匹配行中选取其它关键词,再次进行全文本搜索
SELECT note_text FROM productnotes WHERE Match(note_text) Against(‘anvils’ WITH QUERY EXPANSION);

31. 布尔文本搜索
a. MySQL支持全文本搜索的另外一种形式,称为布尔方式(boolean mode);即使没有FULLTEXT索引列也可以使用布尔方式,但其性能非常低

b. 布尔操作符

  • + 包含,词必须存在
  • - 排除,词必须不出现
  • > 包含,且增加等级值
  • < 包含,且减少等级值
  • * 词尾通配符

SELECT note_text FROM productnotes WHERE Match(note_text) Against(‘heavy -rope*’ IN BOOLEAN MODE); // 找出包含heavy但不包含任意以rope开始的词的行
SELECT note_text FROM productnotes WHERE Match(note_text) Against(‘+rabbit +bait’ IN BOOLEAN MODE); // 包含rabbit且包含bait的行
SELECT note_text FROM productnotes WHERE Match(note_text) Against(‘rabbit bait’ IN BOOLEAN MODE); // 包含rabbit或者包含bait的行


32. 数据插入
a. 插入完整行
INSERT INTO Customers VALUES(NULL, ‘gigglesun’, ‘High tech department’, ‘Shen Zhen’, ‘CA’, ‘518129’, ‘CHINA’, ‘Giggle Sun’, NULL);
INSERT INTO Customers(cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) VALUES(‘sql’, ‘HF’ ‘He Fei’, ‘CA’, ‘123456’, ‘CHINA’, ‘Giggle Sun’, NULL); // 不依赖表定义顺序,比第一种安全
b. 插入时省略某一列的值的条件是该列定义为允许为NULL值或具有默认值
c. 插入操作比较耗时,如果数据检索最重要,可通过INSERT LOW_PRIORITY INTO来降低插入语句的优先级;这同样适用于UPDATE和DELETE语句
d. 插入多行可以使用多个INSERT语句组合在一起一次提交也可以将多个VALUES用逗号分开
INSERT INTO Customers VALUES(
NULL, ‘gigglesun’, ‘High tech department’, ‘Shen Zhen’, ‘CA’, ‘518129’, ‘CHINA’, ‘Giggle Sun’, NULL);
INSERT INTO Customers(cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) VALUES(
‘sql’, ‘HF’ ‘He Fei’, ‘CA’, ‘123456’, ‘CHINA’, ‘Giggle Sun’, NULL);
或者
INSERT INTO Customers(cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) VALUES(
‘sql’, ‘HF’ ‘He Fei’, ‘CA’, ‘123456’, ‘CHINA’, ‘Giggle Sun’, NULL),(‘sqf’, ‘DG’ ‘Dongguan’, ‘CA’, ‘123456’, ‘CHINA’, ‘Giggle Sun’, NULL);

e. 插入检索结果

INSERT INTO custormers(a, b, c) SELECT a, b, c FROM custnew;


33. 数据更新
a. UPDATE 语句包括要更新的表;列名和新值;确定要更新行的过滤条件
UPDATE customers SET cust_email = ‘[email protected]’ WHERE cust_id = 10007;
b. UPDATE更新某行失败后数据会回滚到初始状态, 为即使发生错误也继续,可使用IGNORE关键字
UPDATE IGNORE customers SET cust_email = ‘[email protected]’ WHERE cust_id = 10007;

34. 删除数据
a. DELETE语句只是删除表中的行,即使删除所有行也不删除表本身
DELETE FROM customers WHERE cust_id = 10007;
b. 删除表中的所有行使用TRUNCATE TABLE比DELETE语句效率要高,TRUNCATE 是删除原来的表并新建一个表

35. 创建表
a. 创建表时表名必须不存在,如存在,将出错, 可用CREATE TABLE tablename IF NOT EXISTS来避免;可指定多个主键:PRIMARY KEY(a, b);
CREATE TABLE orderitems
(
order_num int NOT NULL ,
order_item int NOT NULL ,
prod_id char(10) NOT NULL ,
quantity int NOT NULL ,
item_price decimal(8,2) NOT NULL ,
PRIMARY KEY (order_num, order_item)
) ENGINE=InnoDB;
b. 每个表只允许一个AUTO_INCREMENT列,AUTO_INCREMENT列必须被索引,如成为主键和FULLTEXT等. 可以用SELECT last_insert_id();

c. MySQL支持以下常用引擎

  • InnoDB: 支持事务处理,但不支持全文本搜索
  • MyISAM: 支持全文本搜索,但不支持事务处理
  • MEMORY: 等同于MyISAM,数据存储在内存中,速度更快
d. 外键不能跨引擎: 使用一个引擎的表不能应用具有使用不同引擎的表的外键

36. 更新表
a. 更新表的定义,可使用ALTER TABLE语句,理想状态下,表在创建后不应再被更新
ALTER TABLE vendors ADD vend_phone CHAR(20); 添加列
ALTER TABLE vendors DROP COLUMN vend_phone; 删除列
ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_orders FOREIGN KEY (order_num) REFERENCES orders (order_num); 定义外键
b. 删除表
DROP TABLE tablename;
c. 重命名表
RENAME TABLE tablename1 TO tablename2;

37. 视图(ViEW)
a. 视图是虚拟的表,视图不包含数据,只包含查询语句;
SELECT cust_name, cust_contact FROM customers, orders, orderitems WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num AND prod_id = ‘TNT2’; // 交换WHERE语句后表的顺序结果不变
采用视图的方法
CREATE VIEW productcustomers AS SELECT cust_name, cust_contact, prod_id FROM customers, orders, orderitems WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num;
SHOW FULL TABLES;
+——————+————+
| Tables_in_forta | Table_type |
+——————+————+
| customers | BASE TABLE |
| orderitems | BASE TABLE |
| orders | BASE TABLE |
| productcustomers | VIEW |
| productnotes | BASE TABLE |
| products | BASE TABLE |
| vendors | BASE TABLE |
+——————+————+
SELECT cust_name, cust_contact FROM productcustomers WHERE prod_id = ‘TNT2’;
b. 视图操作
CREATE VIEW viewname; 增
DROP VIEW viewname;删
先DROP再CREATE;或者CREATE OR REPLACE VIEW; 改
SHOW FULL TABLES; 查
SHOW CREATE VIEW viewname; 查看创建视图的语句

c. 视图的作用

  • 重用SQL语句,简化复杂的SQL操作
  • 保护数据,使用表的部分而不是整个表,通过视图可以授予用户表的特定部分的访问权限
  • 更改数据格式和表示

38. 存储过程(Stored Procedures)
a. 存储过程是为以后的使用而保存的一条或多条 MySQL语句的集合
b. 存储过程相关操作
DELIMITER //
CREATE PROCEDURE ordertotal(
IN onumber INT,
OUT ototal DECIMAL(8,2)
)
BEGIN
SELECT SUM(item_price*quantity)
FROM orderitems
WHERE order_num = onumber
INTO ototal;
END //
DELIMITER ; //创建
SHOW PROCEDURE STATUS WHERE DB = ‘forta’; // 查询
mysql> SHOW PROCEDURE STATUS LIKE ‘ordertotal’;
SHOW CREATE PROCEDURE ordertotal; // 查询创建语句
CALL ordertotal(20005,@total);// 调用存储过程
mysql> SELECT @total;

39.游标(cursor)
a. 游标是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果的集合。

b. MySQL游标只能用于存储过程(和函数)。

DELIMITER //
CREATE PROCEDURE processorders_copy()
BEGIN
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE t DECIMAL(8,2);
DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=TRUE;
CREATE TABLE IF NOT EXISTS ordertotals
(
    order_number INT,
    total DECIMAL(8,2)
)ENGINE=MyISAM;
OPEN ordernumbers;
REPEAT
    FETCH ordernumbers INTO o;
    CALL ordertotal(o, t);
    INSERT INTO ordertotals(order_number, total) VALUES(o, t);
UNTIL done END REPEAT;
CLOSE ordernumbers;
END //
DELIMITER ;
40.触发器(TRIGGER)
a. 触发器是MySQL响应DELETE、INSERT、UPDATE语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句)

b. 创建触发器需要包含:

  • 唯一的触发器名称
  • 触发器关联的表
  • 触发器应该响应的活动(DELETE、INSERT、UPDATE)
  • 触发器何时执行(响应活动前或活动后)
c. 触发器的使用
查询触发器属性
SELECT trigger_schema, trigger_name, action_statement FROM information_schema.triggers;
SELECT* FROM information_schema.triggers;
SHOW TRIGGERS;
DELETE 触发器
CREATE TABLE IF NOT EXISTS test_orders
(
order_num int NOT NULL AUTO_INCREMENT,
order_date datetime NOT NULL ,
cust_id int NOT NULL ,
PRIMARY KEY (order_num)
) ENGINE=InnoDB;
DELIMITER //
CREATE TRIGGER deleteorder BEFORE DELETE ON test_orders FOR EACH ROW
BEGIN
INSERT INTO archive_orders(order_num, order_date, cust_id)
VALUES(OLD.order_num, OLD.order_date, OLD.cust_id);
END //
DELIMITER ;
INSERT 触发器
CREATE TABLE test1(a1 INT);
CREATE TABLE test2(a2 INT);
CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE test4(
a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
b4 INT DEFAULT 0
);
delimiter //
CREATE TRIGGER testref BEFORE INSERT ON test1
FOR EACH ROW
BEGIN
INSERT INTO test2 SET a2 = NEW.a1;
DELETE FROM test3 WHERE a3 = NEW.a1;
UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
END; //
delimiter ;
INSERT INTO test3 (a3) VALUES
(NULL), (NULL), (NULL), (NULL), (NULL),
(NULL), (NULL), (NULL), (NULL), (NULL);
INSERT INTO test4 (a4) VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0);
INSERT INTO test1 VALUES (1), (3), (1), (7), (1), (8), (4), (4);

d. NEW和OLD

  • DELETE触发器中可以通过引用名为OLD的虚拟表访问被删除的行,OLD只读
  • UPDATE触发器中可以通过引用名为OLD的虚拟表访问更新前的值,OLD只读;可以通过引用名为NEW的虚拟表访问更新后的值(在BEFORE UPDATE中,可以更新NEW中的值)
  • INSERT触发器中可以通过引用名为NEW的虚拟表访问被插入的行(在BEFORE INSERT中,可以更新NEW中的值)

41.事务处理(transactionprocessing)

a. 事务处理用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行

  • 事务(transaction)指一组SQL语句
  • 回退(rollback) 指撤销指定SQL语句的过程
  • 提交(commit) 指将未储存的SQL语句结果写入数据库表
  • 保留点(savepoint) 指事务处理中设置的临时占位符(place-holder),用户可以对其进行回退,比回退整个事务粒度要细些

b. 仅UPDATE/DELETE/INSERT语句可回退,语句块中的DROP/CREATE等操作不会撤销

参考:MySQL必知必会

猜你喜欢

转载自blog.csdn.net/gigglesun/article/details/51404496
41
今日推荐