《MYSQL必知必会》读书笔记

背景

sql真的很好,不骗你。

正文

如何检索出有不同值的列表呢?

解决办法是使用DISTINCT关键字,顾名思义,此关键字指示MySQL 只返回不同的值。
SELECT DISTINCT vend_id告诉MySQL只返回不同(唯一)的 vend_id行。如果使用 DISTINCT关键字,它必须直接放在列名的前面。

限制结果条数

SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。为了返回第一行或前几行,可使用LIMIT子句。
例如:LIMIT 5指示MySQL返回不多于5行。LIMIT 5, 5指示MySQL返回从行5开始的5行。
注意:行0 检索出来的第一行为行0而不是行1。因此,LIMIT1,1 将检索出第二行而不是第一行。

排序

关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。
为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。ORDER BY子句取一个或多个列的名字,据此对输出进行排序。
通常,ORDERBY子句中使用的列将是为显示所选择的列。但是,实际上并不一定要这样,用非检索的列排序数据是完全合法的。
为了按多个列排序,只要指定列名,列名之间用逗号分开即可。

指定排序方向

数据排序不限于升序排序(从A到Z)。这只是默认的排序顺序,还可以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。

and、or

SQL(像多数语言一样)在处理OR操作符前,优先处理AND操作符。
任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认计算次序,即使它确实是你想要的东西也是如此。使用圆括号没有什么坏处,它能消除歧义。

IN操作符

IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清单,全都括在圆括号中。

NOT操作符

WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。

LIKE操作符

百分号(%)通配符

%表示任何字符出现任意次数。

下划线(_)通配符

下划线的用途与%一样,但下划线只匹配单个字符而不是多个字符。

正则

REGEXP后所跟的东西作为正则表达式处理。
\.匹配.,所以只检索出一行。这种处理就是所谓的转义。

拼接

拼接(concatenate) 将值联结到一起构成单个值。
Concat()拼接串,即把多个串连接起来形成一个较长的串。
Concat()需要一个或多个指定的串,各个串之间用逗号分隔。
Trim函数:MySQL除了支持RTrim()(正如刚才所见,它去掉 串右边的空格),还支持LTrim()(去掉串左边的空格)以及 Trim()(去掉串左右两边的空格)。

别名

别名(alias)是一个字段或值 的替换名。别名用AS关键字赋予。

执行算术计算

例:expanded_price列为一个计算字段,此计算为quantity*item_price。客户机应用现在可以使用这个新计算列,就像使用其他列一样。

函数

文本处理函数

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() 返回一个日期的年份部分

数值处理函数

数值处理函数仅处理数值数据。这些函数一般主要用于代数、三角或几何运算,因此没有串或日期—时间处理函数的使用那么频繁。

汇总数据

聚集函数

聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数
AVG() 返回某列的平均值:只用于单个列,只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出。为了获得多个列的平均值,必须使用多个AVG()函数。
COUNT() 返回某列的行数:如果指定列名,则指定列的值为空的行被COUNT() 函数忽略,但如果COUNT()函数中用的是星号(*),则不忽略。
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和

group by

SELECT子句顺序

SELECT 要返回的列或表达式 是
FROM 从中检索数据的表 仅在从表选择数据时使用
WHERE 行级过滤 否
GROUP BY 分组说明 仅在按组计算聚集时使用
HAVING 组级过滤 否
ORDER BY 输出排序顺序 否
LIMIT 要检索的行数 否

子查询

子查询(subquery),即嵌套在其他查询中的查询。
在SELECT语句中,子查询总是从内向外处理。

关联查询

如果数据存储在多个表中,怎样用单条SELECT语句检索出数据?

答案是使用联结。简单地说,联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。

组合查询

执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回。这些组合查询通常称为并(union)或复合查询(compound query)。
有两种基本情况,其中需要使用组合查询:在单个查询中从不同的表返回类似结构的数据; 对单个表执行多个查询,按单个查询返回数据。

UNION使用

UNION的使用很简单。所需做的只是给出每条SELECT语句,在各条语句之间放上关键字UNION。
UNION中的每个查询必须包含相同的列、表达式或聚集函数。
UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔。
列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型。
在使用 UNION时,重复的行被自动取消。这是UNION的默认行为,但是如果需要,可以改变它。事实上,如果想返回所有匹配行,可使用UNION ALL而不是UNION。

对组合查询结果排序

SELECT语句的输出用ORDER BY子句排序。在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一 部分的情况,因此不允许使用多条ORDER BY子句。虽然ORDER BY子句似乎只是最后一条SELECT语句的组成部分,但实际上MySQL将用它来排序所有SELECT语句返回的所有结果。

引擎类型

与其他DBMS一样,MySQL有一个具体管理和处理数据的内部引擎。在你使用CREATE TABLE语句时,该引擎具体创建表,而在你使用SELECT语句或进行其他数据库处理时,该引擎在内部处理你的请求。多数时候, 此引擎都隐藏在DBMS内,不需要过多关注它。
但MySQL与其他DBMS不一样,它具有多种引擎。它打包多个引擎,这些引擎都隐藏在MySQL服务器内,全都能执行CREATE TABLE和SELECT 等命令。
为什么要发行多种引擎呢?因为它们具有各自不同的功能和特性,为不同的任务选择正确的引擎能获得良好的功能和灵活性。
常用的引擎

  1. InnoDB是一个可靠的事务处理引擎, 它不支持全文本搜索;
  2. MEMORY在功能等同于MyISAM,但由于数据存储在内存(不是磁盘) 中,速度很快(特别适合于临时表);
  3. MyISAM是一个性能极高的引擎,它支持全文本搜索,但不支持事务处理。

视图

视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。

使用视图

  1. 视图用CREATE VIEW语句来创建。
  2. 使用SHOW CREATE VIEW viewname;来查看创建视图的语句。
  3. 用DROP删除视图,其语法为DROP VIEW viewname;

用处

  1. 利用视图简化复杂的联结,隐藏复杂的SQL。
  2. 用视图重新格式化检索出的数据。
  3. 用视图过滤不想要的数据。
  4. 使用视图与计算字段。

总结

视图为虚拟的表。它们包含的不是数据而是根据需要检索数据的查询。视图提供了一种MySQL的SELECT语句层次的封装,可用来简化数据处理以及重新格式化基础数据或保护基础数据。

事务

事务(transaction)指一组SQL语句;
回退(rollback)指撤销指定SQL语句的过程;
提交(commit)指将未存储的SQL语句结果写入数据库表;
保留点(savepoint)指事务处理中设置的临时占位符(place-holder),你可以对它发布回退(与回退整个事务处理不同)。

控制事务处理

管理事务处理的关键在于将SQL语句组分解为逻辑块,并明确规定数 据何时应该回退,何时不应该回退。

标识事务的开始

START TRANSACTION

使用ROLLBACK

ROLLBACK命令用来回退(撤销)MySQL语句,一条ROLLBACK语句回退 START TRANSACTION之后的所有语句

使用COMMIT

一般的MySQL语句都是直接针对数据库表执行和编写的。这就是所谓的隐含提交(implicit commit),即提交(写或保存)操作是自动进行的。
但是,在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用COMMIT语句。

隐含事务关闭

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

使用保留点

为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符。这样,如果需要回退,可以回退到某个占位符。这些占位符称为保留点。为了创建占位符,可如下使用SAVEPOINT语句。
SAVEPOINT delete1每个保留点都取标识它的唯一名字,以便在回退时,MySQL知道要回退到何处。为了回退到本例给出的保留点,可如下进行:ROLLBACK TO delete1,保留点在事务处理完成(执行一条ROLLBACK或 COMMIT)后自动释放。

注意

默认的MySQL行为是自动提交所有更改。换句话说,任何 时候你执行一条MySQL语句,该语句实际上都是针对表执行的,而且所做 的更改立即生效。为指示MySQL不自动提交更改,需要使用以下语句:set autocommit=0。autocommit标志决定是否自动提交更改,不管有没有COMMIT语句。设置autocommit为0(假)指示MySQL不自动提交更改 (直到autocommit被设置为真为止)。

安全管理

管理用户

mysql数据库有一个名为user的表,它包含所有用户账号。user表有一个名为user的列,它存储用户登录名。

创建用户账号

为了创建一个新用户账号,使用CREATE USER语句
eg:CREATE USER ben IDENTIFIED BY 'p@$$W0rd';

删除

为了删除一个用户账号(以及相关的权限),使用DROP USER语句。
eg:DROP USER ben;

设置访问权限

  • 为看到赋予用户账号的权限,使用SHOW GRANTS FOR。
    eg:SHOW GRANTS FOR ben
  • 有一个权限USAGE ON *.*。USAGE表示根本没有权限,此结果表示在任意数据库和任意表上对任何东西没有权限。
    为设置权限,使用GRANT语句。
    eg:GRANT SELECT ON farmpro.* TO ben;允许用户在farmpro库的所有表上使用SELECT。对该库所有数据只有只读访问权限。
  • GRANT的反操作为REVOKE,用它来撤销特定的权限。
    eg:REVOKE SELECT ON farmpro.* FROM ben这条REVOKE语句取消刚赋予用户bforta的SELECT访问权限。被 撤销的访问权限必须存在,否则会出错。
  • GRANT和REVOKE可在几个层次上控制访问权限:
  1. 整个服务器,使用GRANT ALL和REVOKE ALL;
  2. 整个数据库,使用ON database.*;
  3. 特定的表,使用ON database.table;
  4. 特定的列;
  5. 特定的存储过程。
  • 简化多次授权:可通过列出各权限并用逗号分隔,将多条 GRANT语句串在一起,如下所示:
    eg:GRANT SELECT,INSERT ON farmpro.* TO ben
  • 更改密码
    为了更改用户口令,可使用SET PASSWORD语句。新口令必须如下加密:
    eg:SET PASSWORD FOR ben = PASSWORD(‘n3w P@’)
    SET PASSWORD还可以用来设置你自己的口令,在不指定用户名时,SET PASSWORD更新当前登录用户的口令。
    eg:SET PASSWORD = PASSWORD(‘n3w P@’)

数据库维护

mysql慢查询日志配置

修改/etc/my.cnf文件
slow_query_log = on ##开启慢查询日志
slow_query_log_file = /data/mysql/slow.log ##慢查询日志位置
long_query_time = 2 ##指定达到多少秒才算慢查询

改善性能

mysql配置

MySQL是用一系列的默认设置预先配置的,从这些设置开始通常 是很好的。但过一段时间后你可能需要调整内存分配、缓冲区大 小等。(为查看当前设置,可使用SHOW VARIABLES;和SHOW STATUS;。)

查看活动进程

MySQL一个多用户多线程的DBMS,换言之,它经常同时执行多个任务。如果这些任务中的某一个执行缓慢,则所有请求都会执 行缓慢。如果你遇到显著的性能不良,可使用SHOW PROCESSLIST显示所有活动进程(以及它们的线程ID和执行时间)。你还可以用KILL命令终结某个特定的进程(使用这个命令需要作为管理员登录)。

使用EXPLAIN语句让MySQL解释它将如何执行一条SELECT语句。

索引

必须索引数据库表以改善数据检索的性能。确定索引什么不是一件微不足道的任务,需要分析使用的SELECT语句以找出重复的 WHERE和ORDER BY子句。如果一个简单的WHERE子句返回结果所花的时间太长,则可以断定其中使用的列(或几个列)就是需要索引的对象。

LIKE很慢。一般来说,最好是使用FULLTEXT而不是LIKE。