《MySQL必知必会》书摘
前面的章节介绍的SQL,MySQL等内容,就不记笔记了.
查询数据库信息:status
查询数据库变量:show status 查找使用like
第六章:过滤数据
WHERE 子句操作符
范围值检查
SELECT uid,username FROM t_user WHERE uid BETWEEN 3 AND 6;
范围值检查
SELECT uid,username FROM t_user WHERE username IS NULL;
- 返回的是字段为NULL的列(不是等于0),使用IS NOT NULL可以查询非NULL结果
第七章:数据过滤
组合WHERE 子句
AND OR
AND
与OR
关键字,功能不言而喻,但是在组合使用时AND的优先度高于OR,正确的使用需要使用圆括号明确的分组相应的操作.
IN
SELECT uid,username FROM t_user WHERE uid IN(4,5);
- 为什么要使用IN操作符?
- IN操作符的语法更清楚且直观.
- 在使用IN时,计算的次序更容易管理(因为使用的操作符更少)
- IN操作符一般比OR操作符执行更快.
- IN的最大优点是可以包含其他SELECT语句,使得能够更动态的建立WHERE子句.
NOT
NOT操作符有且只有一个功能,就是否定它之后的任何条件.SELECT uid,username FROM t_user WHERE uid NOT IN(2,5);
第八章:用通配符进行过滤
LIKE操作符
- 使用%可以进行通配搜索,例如:
%l
,a%b
,b%
. - 注意:%不仅匹配一个或多个,还可以匹配0个字符.另外%不可以匹配NULL,是一个例外.
- 使用
_
可以匹配一个字符,但是不能多也不能少.
第九章:用正则表达式进行搜索
select uid,username from t_user where username REGEXP'ab';
- 注意:MYSQL仅支持正则表达式的一个很小的子集.
LIKE
和 REGEXP
的区别
- LIKE匹配整个行,如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不会返回(除非使用了通配符).而REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将会找到它,对应的列将会被返回.这是一个非常重要的区别.
SELECT uid,username FROM t_user WHERE username REGEXP`1000|2000`; - 匹配两个字符串其中的一个.
匹配几个字符之一
SELECT uid,username FROM t_user WHERE username REGEXP`[123]Tom`;
匹配范围,例如1到5
REGEXP`[1-5]Tom`
- 剩下的内容基本参考正则的语法,就不记笔记了,但是注意SQL中的预定义字符集不同与java中,请自行查找.
- 匹配字符的出现次数同正则语法中.
第十章:创建计算字段
拼接字段
- 在MySQL中使用Concat()函数拼接两个列
- SELECT Concat(username,uid) FROM t_user;
第十一章:使用数据处理函数
SELECT uid, UPPER(username) AS username_upcase FROM t_user;
- 常用的文本处理函数
Left()
返回左侧的字符Length()
返回字符串的长度Locate()
找出字符串的一个子串Lower()
将串转小写LTrim()
去掉串左边的空格RTrim()
去掉右边的字符Soundex()
去掉串的SOUNDEX值- SOUNDEX是一个将任何字符串转换为描述其语音表示的字母数字模式的算法.考虑了类似的发音字符和音节,能够对字符串进行发音对比而不是字符的对比.该算法不是SQL的概念,但是大多数DBMS都支持.
- 应用场景:查寻发音类似的字符
- SubString() 返回子串的字符
- Upper() 将串转换为大写
第十二章:汇总数据
聚合函数(aggregate function)运行在行组上,计算和返回单个值的函数.
AVG()
平均值COUNT()
行数- Tips:COUNT(*)会包含值,但是指定列名的会忽略.
MAX()
最大值- 会自动忽略NULl值的行
MIN()
最小值- 会自动忽略NULl值的行
SUM()
列值之和- 会自动忽略NULl值的行
第十五章:联结表
1 | SELECT vend_name,prod_name,prod_price |
- 上式使用的是等值联结,这种联结也被称为内部联结.
- 在使用联结时一定不要忘记WHERE子句,否则返回的笛卡尔积比你想象的数据多的多.同时请注意,不正确的过滤条件导致MySQL返回不正确的值.
1 | SELECT vend_name,prod_name,prod_price |
- 语句中的SELECT与前面相同,但是两个表之间的关系是FROM子句的组成部分,以INNER JOIN指定.在使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出.传递给ON的实际条件与传递给WHERE的相同.ANSI SQL标准推荐INNER JOIN语法.
第十七章:组合查询
使用UNION
- 使用时只需要将在给出的每条的语句中加上UNION
- 例:查找价格小于5的所有商品,还包括供应商为1001和1002的所有商品(不考虑价格)
1 | SELECT vend_id,prod_id,prod_price |
- 使用
UNION
的注意事项UNION
必须由两条或两条以上的SELECT
语句组成使用,语句中间使用UNION
分割UNION
中的每个查询必须包含相同的列,表达式或聚合函数- 列数据类型必须兼容,不必完全相同,但是必须是DBMS可以隐式转换的类型
- 如果从多表中查询到了相同的数据,默认是去除重复的,如果需要所有项目使用
UNION ALL
- 使用
UNION
时ORDER BY
子句只能有一次出现,并且作用整个结果
第十八章:全文本搜索 PASS
第十九章:插入数据
- 尽量避免全字段插入,因为这样的SQL语句高度依赖表中列的定义次序,是很不安全的.
- 插入多行每组值用一对圆括号括起来,用逗号分割.
插入检索出的数据 INSERT SELECT
1 | INSERT INTO customers( |
- 注意:虽然上例使用了相同的列名,但其实不要求匹配,甚至MySQL是不关心SELECT返回的列名,它使用的是列的位置.
FROM
中可以使用WHERE
.
第二十章:更新和删除数据
更新数据 UPDATE
UPDATE customers SET cust_email="email@gmail.com" WHERE cust_id=1999;
- 注意:如果不是想要更新全表,一定不要忘记
WHERE
IGNORE关键字
:如果UPDATE
语句更新多行,并且在更新这些行的其中一部分发生错误,则整个UPDATE
操作都会取消,回滚值.为了即使发生错误也进行更新可以使用IGNORE
关键字
删除数据 DELETE
DELETE
不需要列明或者通配符,DELETE
删除整行而不是列,删除指定列使用UPDATE
DELETE
删除行,但是不删除表本身- 如果需要更快的删除,使用
TRUNCATE TABLE
,它完成相同的工作,但是速度更快(因为TRUNCATE
是删除原有的表,并且重新创建一个表,而DELETE
是逐行删除)
第二十一章:创建和操作表
- 创建表时,表名必须不存在,否则报错.如有需要先删除后创建.如果需要在一个表不存在的时候创建使用关键字
IF NOT EXISTS
,这样只有在表名不存在的时候才会创建.
使用主键
PRIMARY KEY(vend_id)
,多主键:PRIMARY KEY(order_num,order_item)
AUTO_INCREMENT
- 使用自增的缺点是插入时都不知道生产的值是谁,可以使用
SELECT last_insert_id();
,该语句将返回最后一个AUTO_INCREMENT
值
设置表字段的默认值:quantity int NOT NULL DEFAULT 1,
MySQL数据库引擎类型
- 在创建表是可以在最后使用
ENGINE=InnoDB
指定引擎,MySQL中具有多个引擎,具有不同的特点和特性 - 常见引擎
InooDB
:一个可靠的事物处理引擎,不支持全文搜索MEMORY
:功能同MYyISAM,但是数据存储在内存中,速度很快(适合添加临时表)MyISAM
:是一个性能极高的引擎,它支持全文本的搜索,但是不支持事物处理.- 注意:外键不能跨引擎使用,即使用一个引擎的表不能引用具有不同引擎表的外键
更新表 ALTER TABLE
- 增加列:
ALTER TABLE vendors ADD vend_phone CHAR(20);
- 删除列:
ALTER TABLE vendors DROP COLUMN vend_phone;
- 增加外键:
ALTER TABLE products ADD CONSTRAINT fk_products_vendors FOREIGN KEY (vend_id) REFERENCES vendors(vend_id)
重命名表:RENAME TABLE customers2 TO customers;
第二十二章:视图
- 我的了解:一个暂时存储数据的虚拟表,时我们可以重启SQL语句,简化操作,保护表中的隐私数据,更改时间格式和表示,视图可以返回与底层表不同格式的数据.
视图的规则和限制
- 视图必须唯一命名,且不能和其他表或视图重名,数量不限
- 视图的创建需要足够的访问权限
- 视图可以嵌套,即可以利用其他视图中检索出的数据构造一个视图
- 检索视图时可以使用
ORDER BY
,这样会覆盖视图中的ORDER BY
- 视图不能索引,也不能有关联的触发器或默认值
- 视图可以和表一起使用,例如联结视图和表进行
SELECT
创建视图
- 使用
CREATE VIEW
语句创建 - 使用
SHOW CREATE VIEW viewname;
来查看创建视图的语句 - 使用
DROP VIEW viewname
删除视图
1 | CREATE VIEW productocustomers AS |
- 视图的其他用途,自行了解
- 利用视图简化复杂的联结
- 使用视图重新格式化检索出的数据,加文本处理函数等
- 用视图过滤不需要的数据
- 使用视图与计算字段
第二十三章:存储过程
- 很多时候需要使用复杂的多条语句才能完成一次操作,这时可以创建存储过程,为之后的使用而保存的一条或多条的MySQL语句.可以看做批文件,但是作用不局限与批处理.
为什么要使用存储过程
- 优点:
- 简化对变动的管理,如果表名或列名有变化,只需要更改存储过程的代码,使用的人甚至不需要这些变化.
- 提高性能,因为使用存储过程比单独使用SQL语句快
- 存在一些只能用在单个请求的MySQL元素和特性,存储过程可以使用它们编写功能更强更灵活的代码(下一章)
- 简而言之:简单,安全,高性能
- 缺点:
- 编写存储过程更复杂,需要更高的技能
- 没有较高的权限不可以创建存储过程
创建存储过程
1 | CREATE PROCEDURE productpricing() |
- 存储过程定义时可以在其中接受参数,在()中定义.
- 注意:如果在命令行中编写存储过程是结束符会使存储过程被错误解析,发生报错.解决办法:修改命令行中的语法分隔符.(自行百度)
使用存储过程
CALL productpricing()
编写带变量复杂的存储过程:PASS
第二十四章:游标
- 好像是在存储过程中创建
创建游标
1 | CREATE PROCEDURE processorders() |
- 使用游标: 打开游标:
OPEN CURSOR
,关闭游标:CLOSE ordernumbers;
- 使用
FETCH
语句访问游标的每一行,FETCH
指定检索什么数据,检索出的数据存储在什么地方.它还向前移动游标中的内部行指针,使下一条FETCH
语句检索下一行(不能重复读取同一行),编写在存储过程中 - 编写过程:pass
第二十五章:触发器
- 如果需要在某些事件发生时自动执行怎么办,例如:售出商品自动减库存,删除行时保留副本
- 触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句:
DELETE INSERT UPDATE
,其他语句不支持触发器
创建触发器
- 创建触发器需要4个条件
- 唯一的触发器名
- 触发器关联的表
- 触发器响应的操作(DELETE,INSERT,UPDATE)
- 触发器何时执行(处理前或处理后)
1 | CREATE TRIGGER newproduct AFTER INSERT ON products FROM EACH ROW SELECT 'Product added`; |
- ps:我自己编写的一直报错,不知道是什么问题,有可能是版本的问题吗.
删除触发器: DROP TRIGGER newproduct;
后面还有视图组合触发器等待:pass
第二十六章:事务处理
注意使用支持事物管理的引擎
概念同java中,保证一组操作不会中途停止,它们或整体执行,或完全不执行,如果发生错误则回退到某个已知的安全的状态
术语
- 事物(
transaction
) 指一组SQL语句 - 回退(
rollback
) 指撤销指定SQL语句的过程 - 提交(
commit
) 指将未存储的SQL语句结果写入数据库表 - 保留点(
savepoint
) 指事物处理中设置的临时占位符(place-holder),你可以对它发布回退(与回退整个事物处理不同)
控制事务处理
1
2
3
4
5
6SELECT * FROM ordertotals;
START TRANSACTION;
DELETE FROM ordertotals;
SELECT * FROM ordertotals;
ROLLBACK;
SELECT * FROM ordertotals;- 开始事务
START TRANSACTION
- 那些语句可以
rollback
:INSERT,UPDATE,DELETE,不能回退CREATE或DROP - 创建保留点:
SAVEPOINT delete1
- 每个保留点具有唯一的名字
- 使用
ROLLBACK TO delete1;
- 保留点越多越好,可以灵活的进行回退
- 事物(
可以修改默认的提交行为: SET autocommit=0
第二十七章:全球化和本地化:设置编码校对等 PASS
第二十八章:访问控制
- 控制用户的权限,保证安全.一般不使用root账户,同Linux一样
- 管理用户,用户存储在mysql表中:
USER mysql; SELECT user FROM user;
创建用户,修改权限,删除用户,具体权限:pass
第二十九章:数据库维护
ANALYZE TABLE 表名
来检查表键是否正常CHECK TABLE orders.orderitems;
- 我不知道这两个语句的不同,检查单表的结果是相同的
- 如果从一个表中删除了大量的数据,使用
OPTIMIZE
来回收使用的空间,优化表的性能.
启动mysql命令行的选项
--help
表示帮助--safe-mode
装载减去某些最佳配置的服务器--verbose
显示全文本消息(为获取更详细的帮助消息与–help联合使用)--version
显示版本信息然后退出
第三十章:改善性能
- mysql是一个多线程多用户的DBMS,可以执行多个任务,如果每一个执行慢,所有的请求都会慢,可以使用
SHOW PROCESSLIST
显示所有的活动进程,还可以使用KILL
结束某个线程(需要管理员登录) - 总是有多种方法编写SELECT语句,尝试联结,并,子查询等,找出最佳的方法
- 使用
EXPLAIN
语句让MySQL解释它将如何执行一个SELECT
语句 - 一般来说存储过程比一条条的SQL快
- 使用正确的数据类型
- 尽量不使用通配符匹配行
- 导入数据是关闭自动提交,因为可能还需要删除索引
SELECT
中有一系列复杂的OR
条件,可以使用多条SELECT
和UNION
语句联结,会极大的改善性能- 索引改善数据检索的性能,但损害数据插入,删除和更新的性能.
LIKE
很慢,使用FULLTEXT
代替
结束 2020/1/12 20:57
《MySQL必知必会》书摘