看完《MySQL必知必会》这本书把自己不怎么清楚的总结一下。
Notes:SQL文件
第一章–了解SQL
数据库(database)保存有组织的数据的容器(通常是一个文件或一组文件)
数据库管理系统(Database Management System)英文缩写:DBMS
结构化查询语言(Structured Query Language)英文缩写:SQL
表:一种结构化的文件,可用来存储某种特定类型的数据。
模式(schema):关于数据库和表的布局及特性的信息。
列(column):表中的一个字段。所有表都是由一个或多个列组成的。
数据类型(datatype):所容许的数据类型。每个表列都有相应的数据类型,它限制(或容许)该列中存储的数据。
行(row):表中的一个记录。
主键(primary key):唯一标识表中每行的这个列成为主键。主键用来表示一个特定的行。
表中的任何列都可以作为主键,只要满足一下条件:
任意两行都不具有相同的主键值;
每个行都必须具有一个主键值(主键列不允许NULL值)。
使用主键的好习惯
- 不更新主键列中的值;
- 不重用主键的值;
- 不在主键列中使用可能会更改的值。
第二章–MySQL简介
MySQL是一种DBMS,即它是一种数据库软件。
第三章–使用MySQL
第四章–检索数据
检索不同的行
多条SQL语句必须以分号 ; 分隔。
SQL语句不区分大小写。
检索不同的行使用DISTINCT关键字,该关键字必须直接放在列名的前面。(例如:SELECT DISTINCT vend_id FROM products;)
不能部分使用DISTINCT关键字,DISTINCT关键字应用于所有列而不仅仅是前置它的列。如果给出SELECT DISTINCT vend_id ,prod_name FROM products;除非指定的两个列都不相同,否则所有行都将被检索出来。
限制结果
SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。为了返回第一行或前几行,可使用LIMIT子句。
例如:
SELECT prod_name FROM products LIMIT 5;
LIMIT还可以指定要检索的开始行和行数
LIMIT 5,5(等同于LIMIT 5 OFFSET 5) 指示MySQL返回从行5开始的5行。第一个数为开始位置,第二个数为要检索的行数。检索出来的第一行为行0而不是行1。在行数不够时,有多少返回多少。
第五章–排序检索数据
排序数据
如果不排序,数据一般将以它在底层表中出现的顺序显示。
关系数据库设计理认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。
按多个列排序
SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price,prod_name;
在多个行具有相同的prod_price值时才对产品按prod_name进行排序。如果 prod_price的值都是唯一的,则不会按prod_name排序。
指定排序方向
通过关键字DESC或ASC指定排序方向。
如果想在多个列上进行降序排序,必须对每个列指定DESC关键字。
如果使用LIMIT,它必须位于ORDER BY之后。
第六章–过滤数据
SELECT prod_name,prod_price FROM products WHERE prod_price BETWEEN 5 AND 10;
BETWEEN AND匹配范围中的所有的值,包括指定的开始的值和结束的值。
NULL用is来判断
SELECT prod_name,prod_price FROM products WHERE prod_price IS NULL;
SELECT prod_name,prod_price FROM products WHERE prod_price IS NOT NULL;
第七章–数据过滤
计算次序
SQL在处理OR操作符前,优先处理AND操作符。例如:
SELECT prod_name,prod_price FROM products WHERE vend_id = 1002 OR vend_id=1003 AND prod_price >= 10;
IN操作符
- 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
- 在使用IN时,计算的次序更容易管理。
- IN操作符一般比OR操作符清单执行更快。
- IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。
MySQL支持使用NOT对IN、BETWEEN和EXISTS子句取反。
第八章-—用通配符进行过滤
通配符
“%”可以匹配任何的东西,但有一个例外,即NULL。
“_”总是匹配一个字符,不能多也不能少。
示例:
SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '_ ton anvil';
SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '% ton anvil';
通配符使用技巧
- 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他的操作符。
- 在确实需要使用通配符时,除非绝对有必要,否则不要把他们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
- 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。
第九章-—用正则表达式进行搜索
第十章-—创建计算字段
拼接字符串
Concat( )
去除空格
RTrim( ):去掉右边空格
LTrim( ):去掉左边空格
Trim( ):去掉左右两边的空格
第十一章-—使用数据处理函数
文本处理函数
函数 | 说明 |
---|---|
Left() | 返回串左边的字符 |
Length() | 返回串的长度 |
Locate() | 找出串的一个子串 |
Lower() | 将串转换为小写 |
LTrim() | 去掉串左边的空格 |
Right() | 返回串右边的字符 |
RTrim() | 去掉串右边的空格 |
Soundex() | 返回串的SOUNDEX值 |
SubString() | 返回子串的字符 |
Upper() | 将串转换为大写 |
常用时间和日期处理函数
函数 | 说明 |
---|---|
AddDate() | 增加一个日期(天、周等) |
AddTime() | 增加一个时间(时、分等) |
CurDate() | 返回当前日期 |
CurTime() | 返回当前时间 |
Date() | 返回日期时间的日期部分 |
DateDiff() | 计算两个日期之差 |
Date_Add() | 高度灵活的日期或时间函数 |
Date_Format() | 返回格式化的日期或时间串 |
Day() | 返回一个日期的天数部分 |
DayOfWeek() | 对于一个日期,返回对应的星期几 |
Hour() | 返回一个时间的小时部分 |
Minute() | 返回一个时间的分钟部分 |
Month() | 返回一个日期的月份部分 |
Now() | 返回当前日期和时间 |
Second() | 返回一个时间的秒部分 |
Time() | 返回一个日期时间的时间部分 |
Year() | 返回一个日期的年份部分 |
数值处理函数
函数 | 说明 |
---|---|
Abs() | 返回一个数的绝对值 |
Cos() | 返回一个角度的余弦 |
Exp() | 返回一个数的指数值 |
Mod() | 返回除操作的余数 |
Pi() | 返回圆周率 |
Rand() | 返回一个随机数 |
Sin() | 返回一个角度的正弦 |
Sqrt() | 返回一个数的平方根 |
Tan() | 返回一个角度的正切 |
第十二章–汇总数据
聚集函数运行在行组上,计算和返回单个值的函数。
函数 | 说明 | 注意点 |
---|---|---|
Avg() | 返回某列的平均值 | 函数忽略列值为NULL的行 |
Count() | 返回某列的行数 | Count("*")对表中的行的数目进行计数,Count(column)忽略NULL值的列 |
Max() | 返回某列的最大值 | 函数忽略列值为NULL的行 |
Min() | 返回某列的最小值 | 函数忽略列值为NULL的行 |
Sum() | 返回某列值之和 | 函数忽略列值为NULL的行 |
聚集不同值
只包含不同的值一般用关键字DISTINCT,例如:
SELECT AVG(DISTINCT prod_price) AS avg_price FROM products WHERE vend_id = 1003;
第十三章–分组数据
GROUP BY使用规定
- GROUP BY子句可以包含任意数目的列。
- 如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。
- GROUP BY子句中列出的每个列都必须是检索列或有效的表达式,不能是聚集函数。
- 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句给出。
- 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
- GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。
SELECT vend_id,COUNT(*) as num_prods FROM products GROUP BY vend_id WITH ROLLUP;
使用WITH ROLLUP关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值。
过滤分组
过滤分组使用HAVING,所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。
HAVING和WHERE的差别
- WHERE在数据分组前进行过滤。
- HAVING在数据分组后进行过滤。
- 导致WHERE排除的行不包括在分组中。
ORDER BY与GROUP BY
ORDER BY | GROUP BY |
---|---|
排序产生的输出 | 分组行。但输出可能不是分组的顺序 |
任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或者表达式,而且必须使用每个选择列表达式 |
不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用 |
第十四章–使用子查询
在SELECT子查询中,子查询总是从内向外处理。
对于能嵌套的子查询的数目没有限制,不过在实际的使用时由于性能的限制,不能嵌套太多的子查询。
子查询必须注意限制有歧义的列名。
第十五章–联结表
笛卡尔积:由于没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。
内部联结
下面的语句查询结果相同:
SELECT vend_name,prod_name,prod_price from vendors INNER JOIN products on vendors.vend_id = products.vend_id;
SELECT vend_name,prod_name,prod_price from vendors ,products WHERE vendors.vend_id = products.vend_id;
第十六章–创建高级联结
自联结
两个SQL说明问题:
SELECT prod_id,prod_name FROM products WHERE vend_id = (SELECT vend_id FROM products WHERE prod_id = 'DTNTR');<br>
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';
自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句。虽然最终的结果是相同的,但有时处理联结远比处理子查询快得多。
自然联结
无论何时对表进行联结,应该至少有一个列出现在不止一个表中。标准的联结返回所有的数据,甚至相同的列多次出现。自然联结排除多次出现,使每个列只返回一次。这个工作自己完成。
外部联结
联结包含了那些在相关表中没有关联的行。这种类型的联结称为外部联结。
SELECT customers.cust_id,orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id;
第十七章–组合查询
第十八章–全文本搜索
第十九章–插入数据
提高性能
可以通过在INSERT和INTO之间添加关键字LOW_PRIORITY。
插入多行
其中单条INSERT语句有多组值,每组值用一对圆括号括起来,用逗号分隔。
INSERT INTO customers(cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)VALUES('XX','XX','XX','XX','XX','XX'),('XX','XX','XX','XX','XX','XX');
优点:可以提高数据库的处理性能,因为MySQL用单条的INSERT语句处理多个插入比使用多条INSERT语句快。
插入检索出的数据
INSERT INTO customers(cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)SELECT cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country FROM custnew;
第二十章–更新和删除数据
UPDATE customers SET cust_email = NULL WHERE cust_id = 10005;
DELETE FROM customers WHERE cust_id = 10006;
如果想从表中删除所有行,TRUNCATE TABLE语句,速度更快。(原因:删除原来的表,并重新创建一个表,而不是逐行删除表中的数据)
第二十一章–创建和操作表
每张表只允许一个AUTO_INCREMENT列,而且它必须被索引。
确定AUTO_INCREMENT值:SELECT last_insert_id();
不同引擎的总结
- InnoDB是一个可靠的事务处理引擎,它不支持全文搜索。
- MEMORY在功能等同与MyISAM,但由于数据存储在内存中,速度很快(特别适合临时表)。
- MyISAM是一个性能极高的引擎,它支持全文文本搜索,但不支持事务处理。
第二十二章–使用视图
第二十三章–使用存储过程
第二十四章–使用游标
第二十五章–使用触发器
我的MySQL版本5.6.38,不支持书上面的SQL语句。查看版本:
SELECT version();