MySQL必知必会

第一章 使用MySQL

  1. 使用数据库,USE crashcourse;
  2. 展示数据库,SHOW DATABASES;
  3. 展示数据表,SHOW TABLES;
  4. 展示数据列,SHOW COLUMNS FROM customers;
  5. 显示广泛的服务器状态信息,SHOW STATUS;
  6. 显示创建特定数据库或表的MySQL语句,SHOW CREATE DATABASE SHOW CREATE TABLE;
  7. 显示授予用户的安全权限,SHOW GRANTS;
  8. 显示服务器错误或警告消息,SHOW ERRORS 和 SHOW WARNINGS;

第二章 检索数据

  1. SELECT prod_name

    FROM products;

  2. SELECT prod_id, prod_name, prod_price

    FROM products;

  3. SELECT * FROM product;

  4. SELECT DISTINCT vend_id

    FROM products;

  5. SELECT prod_name

    FROM products

    LIMIT 5;

  6. SELECT prod_name

    FROM products

    LIMIT 10, 5;指示MySQL返回从行10开始的5行。

  7. SELECT products.prod_name

    FROM products;

  8. SELECT products.prod_name

    FROM crashcourse.products;

第三章 排序检索数据

  1. SELECT prod_name

    FROM products

    ORDER BY prod_name;

  2. SELECT prod_id, prod_name, prod_price

    FROM products

    ORDER BY prod_price, prod_name;

  3. SELECT prod_name

    FROM products

    ORDER BY prod_name DESC;

  4. 注意:多个字段排序时,DESC字段只会作用在其前面字段

第四章 过滤数据

  1. SELECT prod_name

    FROM products

    WHERE prod_price = 2.50;

  2. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name = 'fuses';

    结果 Fuses 3.42

    因为MySQL在执行匹配时默认不区分大小写

  3. SELECT prod_name, prod_price

    FROM products

    WHERE prod_price <10;

  4. SELECT prod_name, prod_price

    FROM products

    WHERE prod_price <= 10;

  5. SELECT vend_id, prod_name

    FROM products

    WHERE vend_id <> 1003;

  6. SELECT vend_id, prod_name

    FROM products

    WHERE vend_id != 1003;

  7. SELECT prod_name, prod_price

    FROM products

    WHERE prod_price BETWEEN 5 AND 10;(包括开始和结束)

  8. SELECT prod_name

    FROM products

    WHERE prod_price IS NULL;

第五章 数据过滤

  1. SELECT prod_id, prod_name, prod_price

    FROM products

    WHERE vend_id = 1003 AND price <= 10;

  2. SELECT prod_name, price

    FROM products

    WHERE vend_id = 1003 OR vend_id = 1002;

  3. SELECT prod_name, prod_price

    FROM products

    WHERE (vend_id = 1002 OR vend_id = 1003) AND prod_price <= 10; 因为AND的优先级大于OR

  4. SELECT prod_name, prod_price

    FROM products

    WHERE vend_id IN (1002, 1003)

    ORDER BY prod_name;

  5. 特点:

    1. 在使用长的合法清单时,IN操作符比OR操作符更加直观。
    2. IN操作符一般执行比OR操作符更快。
    3. 在使用IN操作符时,计算的次序更加容易管理(表达式长度较少)。
    4. IN最大的优点是能包含其他的SELECT语句,使得能更加动态得建立WHERE子句。
  6. NOT,有且仅有一个功能,否定它之后所跟的任何条件。

  7. SELECT prod_name, prod_price

    FROM products

    WHERE vend_id NOT IN (1002, 1003)

    ORDER BY prod_name;

  8. MySQL支持NOT对IN\BETWEEN\EXISTS取反,和其他的DBMS相差较大。

第六章 用通配符进行过滤

  1. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name LIKE 'jet%';(%可以匹配任意字符0次或任意次)。

  2. 注意:头部和尾部的空格,会导致匹配不上。

  3. 注意:虽然通配符可以匹配任何字符,有一个字符例外NULL。

  4. '_'通配符,匹配任意字符,注意,只能匹配单个字符,而不能匹配字符串。

  5. 使用通配符的技巧。

    1. 不要过度使用通配符,如果能用其他字符代替,尽量使用其他操作符。
    2. 在确实需要使用通配符时,除非绝对有必要,不要把他放在搜索模式的首部。
    3. 仔细注意通配符的位置。

第七章 用正则表达式进行搜索

  1. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name REGEXP '1000'

    ORDER BY prod_name;

  2. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name REGEXP '.000'

    ORDER BY prod_name;

  3. 注意:BINARY关键字可以区分大小写。

  4. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name REGEXP BINARY 'JetPack .000'

    ORDER BY prod_name;

  5. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name REGEXP '[123] ton'

    ORDER BY prod_name;(返回1 ton 或 2 ton 或 3 ton)

  6. 匹配范围,[0123456789] 显得很长,因此[0-9];[abcdefghijklmnopqrstuvwxyz]显得很长,因此[a-z]。

  7. 反义字符\ \ 如果匹配'.',则'\\.'。

  8. 字符类

    1. [:alnum:] 任意字母和数字,[0-9a-zA-Z]
    2. [:alpha:]任意字符,[a-zA-Z]
    3. [:blank:]空格和制表,同[\\t]
    4. [:cntrl:]ASCII控制字符,同(ASCII0-31 和 127)
    5. [:digit:]任意数字
    6. [:graph:]与[:print:]相同,但不包括空格
    7. [:lower:]任意小写字母
    8. [:print:]任意可打印字符
    9. [:punct:]既不在[:alnum:]又不在[:cntrl:]中的字符
    10. [:space:]包括空格在内的任意空白字符,同([\\t\\f\\n\\r\\v])
    11. [:upper:]任意大写字母
    12. [:xdigit:]任意16进制数字,同([a-fA-F0-9)
  9. 重复元字符

    1. * 0或多个匹配
    2. + 1或多个匹配
    3. ? 0或1个匹配
    4. {n}指定数目的匹配
    5. {n,} 不小于指定数目的匹配
    6. {n, m}匹配数目的范围(m不超过255)
  10. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name REGEXP '[[:digit:]]{4}'

    ORDER BY prod_name;

  11. 定位元字符

    1. ^ 文本开头
    2. $ 文本结尾
    3. [[:<:]] 词开头
    4. [[:>:]] 词结尾
  12. SELECT prod_name, prod_price

    FROM products

    WHERE prod_name REGEXP '[1]'

    ORDER BY prod_name;

第八章 创建计算字段

  1. SELECT Concat(vend_name, ' (', vend_country, ')')

    FROM vendors

    ORDER BY vend_name;

  2. Trim()函数,MySQL支持RTrim函数,LTrim函数,Trim函数,去除字符串左边空格、右边空格、两端空格。

  3. 列别名,通过计算得到的新的字段仅仅是一个值,应用不好引用它,因此需要引入别名

    SELECT Concat(vend_name, ' (', vend_country, ')')

    AS vend_title

    FROM vendors

    ORDER BY vend_name;

  4. SELECT prod_id,

    ​ quantity,

    ​ item_price,

    ​ quantity * item_price AS expanded_price

    FROM orderitems

    WHERE order_num = 20005;

第九章 使用数据处理函数

  1. SELECT vend_name Upper(vend_name) AS vend_name_upcase

    FROM vendors

    ORDER BY vend_name;

  2. 常用文本处理函数

    1. Left()返回串左边的字符
    2. Length()返回串的长度
    3. Locate()找出串的一个字串
    4. Lower()将串转换为小写
    5. LTrim()去掉串左边的空格
    6. Right()返回串右边的字符
    7. RTrim()去掉串右边的空格
    8. Soundex()返回串的soundex值
    9. SubString()返回字串的字符
    10. Upper()返回串的大写
  3. 日期处理函数

    1. AddDate()增加一个日期
    2. AddTime()增加一个时间
    3. CurDate()返回当前日期
    4. CurTime()返回当前时间
    5. Date()返回日期时间的日期部分
    6. DateDiff()计算两个日期之差
    7. Date_Add()高度灵活的日期计算函数
    8. Date_Format()返回一个格式化的日期或时间串
    9. Day()返回一个日期的天数
    10. DayOfWeek()对于一个日期,返回对应星期几
    11. Hour()
    12. Minute()
    13. Month()
    14. Now()
    15. Second()
    16. Time()
    17. Year()
  4. 建议使用完整的4位数字年份。

  5. SELECT cust_id, order_num

    FROM orders

    WHERE Date(order_date) = '2005-09-01';

  6. SELECT cust_id, order_num

    FROM orders

    WHERE Date(order_date) BETWEEN '2005-09-01' AND '2005-09-31';

  7. SELECT cust_id, order_num

    FROM orders

    WHERE Year(order_date) = 2005 AND Month(order_date) = 9;

  8. 数值处理函数

    1. Abs() 绝对值
    2. Cos() 返回一个角度的余弦
    3. Exp() 返回一个数的指数值
    4. Mod() 取模
    5. Pi() 返回圆周率
    6. Rand() 返回一个随机数
    7. Sin() 正弦
    8. Sqrt() 返回一个数的平方根
    9. Tan() 正切

第十章 汇总数据

  1. 确定表中的行数

  2. 获取表中行组的和

  3. 找出表列的最大值、最小值和平均值

  4. SELECT AVG(prod_price) AS avg_price

    FROM products;

  5. SELECT AVG(prod_price) AS avg_price

    FROM products

    WHERE vend_id = 1003;

  6. SELECT Count(*) AS cust_num

    FROM customers;

  7. SELECT MAX(prod_price) AS max_price

    FROM products;

  8. SELECT MIN(prod_price) AS min_price

    FROM products;

  9. SELECT SUM(quantity) AS items_ordered

    FROM orderitems

    WHERE order_num = 20005;

  10. SELECT SUM(quanity * item_price) AS total_price

    FROM orderitems

    WHERE order_num = 20005;

  11. SELECT AVG(DISTINCT prod_price) AS avg_price

    FROM products

    WHERE vend_id = 1003;

  12. SELECT COUNT(*) AS num_items,

    ​ MIN(prod_price) AS min_price,

    ​ MAX(prod_price) AS max_price,

    ​ AVG(prod_price) AS avg_price

    FROM products;

  13. 注意,DISTINCT只能用于AVG,COUNT(),不可用于COUNT(*),用于MAX,MIN则没有必要。

第十一章 分组数据

  1. SELECT vend_id COUNT(*) AS num_prods

    FROM products

    GROUP BY vend_id;

  2. GROUP BY规定

    a) GROUP BY字句可以包含任意数目的列。使得能够对分组进行嵌套,为数据分组提供更细致的控制。

    b) 如果GROUP BY嵌套,数据将在最后的分组进行汇总。换句话说,在建立分组时,指定的所有列都一起计算。

    c) GROUP BY子句中列出的每个列都必须时检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句指定相同的表达式,不能使用别名

    d) 除聚集函数,SELECT语句中的每个列都必须在GROUP BY子句中给出。

    e) 分组列中国有NULL,则NULL将会作为一个分组返回。

    f) GROUP BY子句出现在WHERE之后,ORDER BY之前。

  3. 过滤分组,WHERE过滤行,HAVING过滤分组。

  4. SELECT cust_id, COUNT(*) AS orders

    FROM orders

    GROUP BY cust_id

    HAVING COUNT(*) >= 2;

  5. SELECT vend_id, COUNT(*) AS nup_prods

    FROM products

    WHERE prod_price >= 10

    GROUP BY vend_id

    HAVING COUNT(*) >= 2;

  6. SELECT order_num, SUM(quanity * item_price) AS ordertotal

    FROM orderitems

    GROUP BY order_num

    HAVING SUM(quantity * item_price) >= 50;

  7. SELECT order_num, SUM(quanity * item_price) AS ordertotal

    FROM orderitems

    GROUP BY order_num

    HAVING SUM(quantity * item_price) >= 50

    ORDER BY ordertotal;

第十二章 使用子查询

  1. SELECT order_num

    FROM orderitems

    WHERE prod_id = 'TNT2';

  2. SELECT cust_id

    FROM orders

    WHERE order_num IN (20005, 20007);

  3. SELECT cust_name, cust_contact

    FROM customers

    WHERE cust_id IN (SELECT cust_id

    ​ FROM orders

    ​ WHERE order_num IN (SELECT order_num

    ​ FROM orderitems

    ​ WHERE prod_id = 'TNT2'));

  4. SELECT cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE order.cust_id = customers.cust_id)

    AS orders

    FROM customers

    ORDER BY cust_name;

第十三章 联结

  1. SELECT vend_name, prod_name, prod_price

    FROM vendors, products

    WHERE vendors.vend_id = products.vend_id

    ORDER BY vend_name, prod_name;

  2. WHERE子句的重要性,在一条SELECT语句中联接几个表时,相应的关系是在运行时构造的,第一个表的每一行与第二个表的每一行配对,如果没有WHERE子句,则会和所有的配对

  3. 笛卡尔积:没有联结条件返回的结果。row1 * row2

  4. SELECT vend_name, prod_name, prod_price

    FROM vendors JOIN products

    ON vendors.vend_id = products.vend_id;

  5. 推荐使用JOIN替代WHERE,尽管WHERE比较简单,但是使用联结语法确保不忘记联结条件,有时这样做也能影响性能

  6. MySQL在运行时关联指定的每个表以处理联结。这种处理非常耗费资源,因此应该仔细,不要联结不必要的表。联结的表越多,性能下降越厉害

  7. 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';

第十四章 创建高级联结

表别名,使用表别名可以缩短SQL语句,允许在单条SELECT语句中多次使用相同的表。

  1. 表别名不仅能用于WHERE子句,还可以用于SELECT的列表、ORDER BY 子句以及语句的其他部分。

  2. 使用自联结而不用子查询,自联结通常作为外部语句替代子查询。

  3. SELECT prod_id, prod_name

    FROM products AS p1, products AS p2

    WHERE p1.vend_id = p2.vend_id

    ​ AND p2.prod_id = 'DTNTR';

  4. SELECT customers.cust_id, orders.order_num

    FROM customers AS c LEFT JOIN orders AS o

    ON c.cust_id = o.cust_id;

  5. SELECT customers.cust_name,

    ​ customers.cust_id,

    ​ COUNT(orders.order_num) AS num_ord

    FROM customers LEFT JOIN orders

    ON customers.cust_id = orders.cust_id

    GROUP BY customers.cust_id;

第十五章 组合查询

单个查询中从不同的表返回类似结构的数据

对单个表执行多个查询,按单个查询返回数据

  1. 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);

  2. SELECT vend_id, prod_id, prod_price

    FROM products

    WHERE prod_price <= 5

    ​ OR vend_id IN (1001, 1002);

  3. UNION从查询结果集自动去除重复的行,可以通过UNION ALL返回所有匹配行。

  4. SELECT vend_id, prod_id, prod_price

    FROM products

    WHERE prod_price <= 5

    UNION ALL

    SELECT vend_id, prod_id, prod_price

    FROM products

    WHERE vend_id IN (1001, 1002);

  5. ORDER BY子句在组合查询UNION中,只能使用一条ORDER BY子句,它必须粗线在最后一条SELECT语句之后。

  6. 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)

    ORDER BY vend_id, prod_price;

第十六章 全文本搜索

MyISAM引擎支持全文本搜索,InnoDB不支持

通配符%,使用LIKE,能够查找包含特殊值或部分值得行

正则表达式匹配列值,可以编写查找所需行得非常复杂得匹配模式

  1. 性能:通配符和正则表达式匹配通常要求MySQL尝试匹配表中所有的行(这种搜索极少使用表索引)。

  2. 明确控制:通配符和正则很难明确控制匹配什么和不匹配什么。

  3. 智能化的结果:通配符和正则不能提供智能化的结果,不区分单个匹配和多个匹配。

  4. SELECT note_text

    FROM productnotes

    WHERE Match(note_text) Against('rabbit');

第十七章 插入数据

  1. INSERT into Customers

    values(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA', NULL, NULL);

  2. INSERT into Customers(cust_name, cust_address, cust_city, cust_state, cust_zip, cust_contry, cust_contact, cust_email)

    values(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA', NULL, NULL);

  3. 一般不要使用没有明确给出列的列表的INSERT语句

  4. INSERT LOW PRIORITY INTO适用于update delete

  5. INSERT INTO customers(cust_id, cust_name)

    SELECT cust_id, cust_name

    FROM custnew;

第十八章 更新和删除数据

  1. 更新表中特定行

  2. 更新表中所有行

  3. UPDATE customers

    SET cust_name = 'The Fudds',

    ​ cust_email = 'elmer@fudd.com'

    WHERE cust_id = 10005;

  4. IGNORE关键字,当更新多行数据的时候,其中一行或多行错误时,整个更新操作会被取消,而IGNORE关键字,当错误发生时更新操作继续进行

  5. DELETE FROM customers

    WHERE cust_id = 10006;

  6. DELETE删除表的内容而不是表

  7. 如果要删除所有行,不要使用DELETE,TRUNCATE TABLE语句,TRUNCATE实际删除表,并重新创建一个表。

  8. 除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATE或DELETE语句。

  9. 保证每个表都有主键,WHERE子句使用它。

  10. UPDATE和DELETE之前,需要先用SELECT进行测试,保证它过滤正确的记录。

第十九章 创建和操纵表

  1. CREATE TABLE customers

    (

    ​ cust_id int NOT NULL AUTO_INCREMENT,

    ​ cust_name char(50) NOT NULL,

    ​ cust_address char(50) NULL,

    ​ cust_city char(50) NULL,

    ​ cust_state char(5) NULL,

    ​ cust_zip char(10) NULL,

    ​ cust_country char(50) NULL,

    ​ cust_contact char(50) NULL,

    ​ cust_email char(255) NULL,

    ​ PRIMARY KEY (cust_id)

    ) ENGINE=InnoDB;

  2. CREATE TABLE orders

    (

    ​ order_num int NOT NULL AUTO_INCREMENT,

    ​ order_date datetime NOT NULL,

    ​ cust_id int NOT NULL,

    ​ PRIMARY KEY (order_num)

    ) ENGINE=InnoDB;

  3. 指定默认值

    CREATE TABLE orderitems

    (

    ​ order_num int NOT NULL,

    ​ order_item int NOT NULL,

    ​ prod_id char(10) NOT NULL,

    ​ quantity int NOT NULL DEFAULT 1,

    ​ item_price decimal(8, 2) NOT NULL,

    ​ PRIMARY KEY (order_num, order_item)

    ) ENGINE=InnoDB;

  4. InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索

  5. MEMORY在功能上等于MyISAM,但是数据存储在内存,速度很快,适合临时表

  6. MyISAM是一个性能极高的引擎,支持全文本搜索,但不支持事务

  7. 混用引擎有一个大缺陷,外键不能跨引擎

  8. ALTER TABLE vendors

    ADD vend_phone CHAR(20);

  9. ALTER TABLE vendors

    DROP COLUMN vend_phone;

  10. ALTER TABLE一种常见用途是定义外键

    ALTER TABLE orderitems

    ADD CONSTRAINT fk orderitems orders

    FOREIGN KEY (order_num) REFERENCES orders(order_num);

  11. 删除表,DROP TABLE customers2;

  12. 重命名表,RENAME TABLE customers2 TO customers;

第二十章 使用视图

  1. 使用视图的原因

    1. 重用SQL语句
    2. 简化复杂的SQL操作。编写查询后,可以方便地重用它而不必知道它的基本查询细节。
    3. 使用表的组成部分而不是整个表
    4. 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限。
    5. 更改数据格式和表示。
    6. 视图仅仅用来查看存储在别处的数据的一种设施,视图本身不包含数据
  2. 视图的规则

    1. 与表名一样,视图必须唯一命名
    2. 可以创建的视图数目没有限制
    3. 创建视图,需要管理员赋予权限
    4. 视图可以嵌套
    5. ORDER BY可用在视图中
    6. 视图不能索引,也不能有关联的触发器或默认值
    7. 视图可以和表一起使用
  3. CERATE 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;

  4. CREATE VIEW vendorlocations AS

    SELECT Concat(RTrim(vend_name), ' (', RTrime(vend_country), ')')

    FROM vendors

    ORDER BY vend_name;

  5. SELECT *

    FROM vendorlocations;

  6. CREATE VIEW customeremaillist AS

    SELECT cust_id, cust_name, cust_email

    FROM customers

    WHERE cust_email IS NOT NULL;

  7. CREATE VIEW orderitemsexpanded AS

    SELECT order_num, prod_id, quantity, item_price,

    ​ quantity*item_price AS expanded_price

    FROM orderitems;

第二十一章 使用存储过程

  1. CREATE PROCEDURE productpricing()

    BEGIN

    ​ SELECT AVG(prod_price) AS priceaverage

    ​ FROM products

    END;

  2. CALL productpricing();

  3. DROP PROCEDURE productpricing;

  4. CREATE PROCEDURE productpricing(

    ​ OUT pl DECIMAL(8,2),

    ​ OUT ph DECIMAL(8,2),

    ​ OUT pa DECIMAL(8,2)

    )

    BEGIN

    ​ SELECT Min(prod_price)

    ​ INTO pl

    ​ FROM products;

    ​ SELECT Max(prod_price)

    ​ INTO ph

    ​ FROM products;

    ​ SELECT Avg(prod_price)

    ​ INTO pa

    ​ FROM products;

    END;

  5. IN(传递给存储过程)

  6. OUT(从存储过程传递出)

  7. INOUT(对存储过程传入和传出)

  8. INTO关键字保存到相应的变量

  9. 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;

  10. CALL ordertotal(20005, @total);

  11. SELECT @total;

第二十二章 使用游标

有时,需要在检索出来的行中前进或后退一行或多行。利用简单的SELECT语句无法得到第一行、下一行或前10行。

  1. CREATE PROCEDURE processorders()

    BEGIN

    ​ DECLARE ordernumbers CURSOR

    ​ FOR

    ​ SELECT order_num FROM orders;

    END;

  2. OPEN ordernumbers;

  3. CLOSE ordernumbers;

  4. CREATE PROCEDURE processorders()

    BEGIN

    ​ -- Declare the cursor

    ​ DECLARE ordernumbers CURSOR

    ​ FOR

    ​ SELECT order_num FROM orders;

    ​ -- Open the cursor

    ​ OPEN ordernumbers;

    ​ -- Close the cursor

    ​ CLOSE ordernumbers;

    END;

  5. CREATE PROCEDURE processorders()

    BEGIN

    ​ -- Declare local variables

    ​ DECLARE o INT;

    ​ -- Declare the cursor

    ​ DECLARE ordernumbers CURSOR

    ​ FOR

    ​ SELECT order_num FROM orders;

    ​ -- Open the cursor

    ​ OPEN ordernumbers;

    ​ -- Get order number

    ​ FETCH ordernumber INTO o;

    ​ -- Close the cursor

    ​ CLOSE ordernumbers;

    END;

  6. CREATE PROCEDURE processorders()

    BEGIN

    ​ -- Declare local variables

    ​ DECLARE o INT;

    ​ -- Declare the cursor

    ​ DECLARE ordernumbers CURSOR

    ​ FOR

    ​ SELECT order_num FROM orders;

    ​ -- Declare continue handler

    ​ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

    ​ -- Open the cursor

    ​ OPEN ordernumbers;

    ​ -- Loop through all rows

    ​ REPEAT

    ​ -- Get order number

    ​ FETCH ordernumber INTO o;

    ​ -- End of loop

    ​ UNTIL done END REPEAT;

    ​ -- Close the cursor

    ​ CLOSE ordernumbers;

    END;

第二十三章 使用触发器

某个表发生更改时,自动执行

DELETE, INSERT, UPDATE语句之后,自动执行的一条MySQL语句(或位于BEGIN和END语句质检的一组语句,其他语句不支持触发器

  1. 唯一的触发器名

  2. 触发器关联的表

  3. 触发器响应的活动

  4. 触发器何时执行(处理之前或之后)

  5. CREATE TRIGGER newproduct AFTER INSERT ON products

    FOR EACH ROW SELECT 'Product added';

  6. 只有表才支持触发器,视图和临时表都不支持

  7. 每个表最多支持6个触发器(每条INSERT、UPDATE和DELETE的之前和之后)

  8. DORP TRIGGER newproduct;

  9. CREATE TRIGGER neworder AFTER INSERT ON orders

    FOR EACH ROW SELECT NEW.order_num;

  10. CREATE TRIGGER deleteorder BEFORE DELETE ON 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;

第二十四章 管理事务处理

事务处理(transaction processing)可以用来维护数据库的完整性,保证成批的MySQL操作要么完全执行,要么完全不执行。

  1. 事务(transaction)指一组SQL语句

  2. 回退(rollback)指撤销指定SQL语句的过程

  3. 提交(commit)指将未存储的SQL语句结果写入数据库表

  4. 保留点(savepoint)指事务处理中设置的临时占位符(place-holder),你可以对它发布回退

  5. 事务开始,START TRANSACTION

  6. SELECT * FROM ordertotals;

    START TRANSACTION;

    DELETE FROM ordertotals;

    ROLLBACK;

    SELECT * FROM ordertotals;

  7. 事务处理用来管理INSERT、UPDATE和DELETE语句,不能回头SELECT语句。不能回退CREATE或DROP操作,虽然可以在事务中使用,但是不能撤销

  8. 事务中不会隐含提交。

    STARTTRANSACTION;

    DELETE FROM orderitems WHERE order_num = 20010;

    DELETE FROM orders WHERE order_num = 20010;

    COMMIT;

  9. ROLLBACK或COMMIT语句执行后,事务会自动关闭

  10. 简单的ROLLBACK和COMMIT语句可以写入或撤销整个事务处理,但是,只是针对简单的事务处理才能这样做,更复杂的事务处理可能需要部分提交或回退

  11. SAVEPOINT delete1;

  12. ROLLBACK TO delete1;

  13. 保留点越多越好,事务处理完成后自动释放,MySQL5以后,也可以用RELEASE SAVEPOINT明确释放。

  14. 关闭自动提交,SET autocommit=0;

第二十五章 全球化和本地化

  1. 字符集字母和符合的集合
  2. 编码某个字符集成员内部表示
  3. 校对字符如何比较的指令
  4. SHOW CHARACTER SET;

第二十六章 安全管理

访问控制

  1. USE mysql;

    SELECT user FROM user;

  2. CREATE USER ben IDENTIFY BY 'p@$$w0rd';

  3. RENAME USER ben TO bforta;

  4. DROP USER bforta;

  5. SHOW GRANTS FOR bforta;

  6. GRANT SELECT ON crashcourse.* TO bforta;

  7. REVOKE SELECT ON crashcourse.* FROM bforta;

    1. 整个服务器,GRANT ALL / REVOKE ALL
    2. 整个数据库,ON database.*;
    3. 特定表,ON database.table;
    4. 特定列;
    5. 特定存储过程;
  8. SET PASSWORD FOR bforta = Password('n3w p@$$w0rd');

第二十七章 数据库维护

  1. 备份数据
    1. mysqldump
    2. mysqlhotcopy
    3. BACKUP TABLE 或 SELECT INTO OUTFILE,RESTORE TABLE复原
    4. FLUSH TABLES备份前刷新未写数据
  2. 数据库维护
    1. ANALYZE TABLE检查表键是否正确
    2. CHECH TABLE
    3. REPAIR TABLE
  3. 诊断启动问题
    1. --help
    2. --safe-mode
    3. --verbose显示全文本信息
    4. --version
  4. 查看日志文件
    1. 错误日志启动关闭问题以及任意关键错误 通常命名为hostname.err,位与data目录中。
    2. 查询日志 所有MySQL活动 通常命名为hostname.log,位于data目录。
    3. 二进制日志 记录更新过数据(或可能更新过数据)的所有语句 hostname-bin,位于data目录。
    4. 缓慢查询日志 记录执行缓慢的任何查询 hostname-slow.log.

第二十八章 改善性能

  1. 遵循硬件建议
  2. 运行在专用服务器上
  3. MySQL一开始是默认设置,过一段时间后,可能需要调整内存分配、缓冲区大小等。SHOW VARIABLES; SHOW STATUS;
  4. 不止一种方法编写同一条SELECT语句。应当试验联结、并、子查询等
  5. 使用EXPLAIN语句让MySQL解释它如何执行一条SELECT语句
  6. 一般来说存储过程比一条一条执行其中的SQL语句要快
  7. 应该总使用正确数据类型
  8. 决不要检索比需求还要多的数据
  9. 在导入数据时应该关闭自动提交,SET AUTOCOMMIT = 0;
  10. 如果有很多OR条件,试试UNION
  11. 索引改善数据检索的性能,但是损害数据插入、删除和更新的性能
  12. LIKE很慢。一般来说最好使用FULLTEXT。

  1. 0-9\\. ↩︎

posted @ 2021-02-20 17:41  桌儿剑仙  阅读(158)  评论(0)    收藏  举报