一、SQL
1、DDL
2、DML
3、DQL
4、DCL
主要包括用户管理和权限控制
1)DCL-管理用户
--查询用户
use mysql
select * from user;--新增用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码'eg:
create user 'haha'@'localhost' identied by '123';
create user 'hehe'@'%' identified by '123'--修改用户密码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码'eg:
alter user 'haha'@'localhost' identified with masql_native_password by '111';--删除用户
DROP USER '用户名'@'主机名'eg:
drop user 'haha'@'localhost';2)DCL-权限控制
mysql中定义了很多种权限,常见的如下:
| 权限 | 说明 | 
|---|---|
| ALL,ALL PRIVILEGES | 所有权限 | 
| SELECT | 查询数据 | 
| INSERT | 插入数据 | 
| UPDATE | 修改数据 | 
| DELETE | 删除数据 | 
| ALTER | 修改表 | 
| DROP | 删除数据库/表/视图 | 
| CREATTE | 创建数据库/表 | 
--权限查询
SHOW GRANTS FOR '用户名'@'主机名'eg:
show grants for 'haha'@'%';
-- 授权
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名'eg:
grant all on test.* to 'haha'@'%';--回收权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名'revoke all on test.* from 'haha'@'%';
二、函数
1、字符串函数
| 函数 | 含义 | 
| concat(s1,s2 ……sn) | 字符串拼接,将s1,s2……sn拼接成一个字符串 | 
| lower(str) | 将字符串s全部转为小写 | 
| uppper(str) | 将字符串s全部转为大写 | 
| lpad(str,n,pad) | 左填充,用字符串pad在str左边填充,达到n个字符串长度 | 
| rpad(str,n,pad) | 右填充,用字符串pad在str右边填充,达到n个字符串长度 | 
| trim(str) | 去掉字符串头部和尾部的空格 | 
| substring(str,start,len) | 返回str字符传中从start位置起的len个长度的字符串 | 
2、数值函数
| 函数 | 含义 | 举例 | 
| ceil(x) | 向上取整 | |
| floor(x) | 向下取整 | |
| mod(x,y) | 取余 | |
| rand() | 获取一个0-1之间的随机数 | |
| round(x,,y) | 求参数x的四舍五入的值,保留y位小数 | |
3、日期函数
| 函数 | 含义 | 
| curdate() | 当前日期 | 
| curtime() | 当前时间 | 
| now() | 返回当前日期和时间 | 
| year(date) | 获取指定日期的年份 | 
| month(date) | 获取指定日期的月份 | 
| day(date) | 获取指定日期的日期 | 
| DATE_ADD(date,INTERVAL expr type) | 返回一个日期/时间值加上一个时间间隔expr后的时间值 | 
| DATEDIFF(date1,date2) | 返回起始时间date1和结束时间date2之间的天数,date1-date2 | 
eg:
select date_add(now(),interval 5 year)
select date_add(now(),interval 5 day)
select date_add(now(),interval 5 month)
4、流程函数
| 函数 | 含义 | |
| if(val,t,f) | 如果val为true,则返回t,否则返回f | |
| ifnull(val1,val2) | 如果val1不为空,则返回val1,否则返回val2 | |
| CASE WHEN val1 THEN res1 …… ELSE default END | 如果val1 为true,则返回res1,否则,返回默认值default | |
| CASE EXP WHEN val1 THEN res1 ELSE default END | 如果exp的值等于val1,则返回res1,否则返回default | 
三、约束
概念:
约束是作用在表中字段上的规则,用于限制存储在表中的数据。
目的:
保证数据库中数据的正确性、有效性和完整性。
分类:
| 约束 | 描述 | 关键字 | 
| 非空约束 | 限制该字段上的数据不能为null | NOT NULL | 
| 唯一约束 | 保证该字段上的所有数据都是唯一不重复的 | UNIQUE | 
| 主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY | 
| 默认约束 | 保存数据时,如果未指定该字段的值,则使用默认值 | DEFAULT | 
| 检查约束(自8.0.16之后) | 保证字段值满足某一条件 | CHECK | 
| 外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY | 
外键
1)添加外键
CREATE TABLE 表名(
字段名,字段类型
……
[CONSTRAINT ] [外键名] FOREIGN KEY (外键字段名)REFERENCES 主表(主表列名)
)
ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (外键字段名) REFERENCES 主表名(主表列名)
eg:
ALTER TABLE epm ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id)
2、删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名
eg:
ALTER TABLE EMP DROP FOREIGN KEY fk_emp_dept_id
3、删除/更新行为
| 行为 | 说明 | 
| NO ACTION | 当在父表中删除/更新记录时,首先检查该记录是否有对应外键,如果有,则不允许删除/更新。(与RESTRICT一致) | 
| RESTRICT | 当在父表中删除/更新记录时,首先检查该记录是否有对应外键,如果有,则不允许删除/更新。(与NO ACTION 一致) | 
| CASCADE | 当在父表中删除/更新记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录 | 
| SET NULL | 当在父表中删除记录时,首先检查该记录是否有对应外键,如果有,则设置子表中该外键值为null(需要该字段允许为null) | 
| SET DEFAULT | 父表有变更时,子表设置成一个默认的值(innodb不支持) | 
4、语法
ALTER TABLE ADD CONSTRAINT 外键名 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名)ON UPDATE CASCADE ON DELETE CASCADE
四、多表查询
1、多表关系
一对多:外键
一对一:表结构拆分,其中一表设置外键为另一表主键
多对多:中间表
2、内连接
语法
隐式内连接
SELECT 字段列表 FROM 表1,表2 WHERE 条件
显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件
3、外连接
1)左外连接
SELECT 字段名 FROM 表1 LEFT [OUTER] JOIN 表2 ON 连接条件
查询左表的所有数据,包含表1和表2 交集部分的数据
2)右外连接
SELECT 字段名 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 连接条件
4、自连接
SELECT 字段名 FROM 表A 表别名A JOIN 表A 表别名B ON 连接条件
自连接查询可以是内连接查询,也可以是外连接查询
5、联合查询 UNION ,UNION ALL
SELECT 字段列表 FROM 表A WHERE 查询条件 ……
UNION [ALL]
SELECT 字段列表 FROM 表B WHERE 查询条件 ……
UNION查询就是把多次查询的结果合并起来,形成一个新的查询结果集。
6、子查询
概念:SQL语句中嵌套SELECT语句,成为嵌套查询,又称子查询。
SELECT * FROM t1 WHERE column1=(SELECT column1 FROM t2)
根据子查询结果不同,分为:
- 标量子查询(子查询结果为单个值)
- 列子查询(子查询结果为单个列)
- 行子查询(子查询结果为单个行)
- 表子查询(子查询结果为多行多列)
根据子查询位置分为:
WHERE之后、FROM之后、SELECT 之后
1)标量子查询
子查询返回的结果是单个值(数值、字符串、日期),是最简单的子查询,称为标量子查询
常用操作符:= 、>=、>、<、<=
2)列子查询
子查询返回的结果是单个列(可以是多行),这种子查询称为列子查询。
常用操作符:IN、NOT IN、ANY、SOME、ALL
3)行子查询
子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
常用操作符:=、<>、IN、NOT IN
4)表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询
常用操作符:IN
五、事务
1、简介
事务是一组操作的组合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体,一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
默认MYSQL的事务是自动提交的,也就是说,当执行一条DML语句的时候,MYSQL会立即隐式的提交事务
2、事务操作
方式一:
1)查看/设置事务的提交方式:
select @@autocommit; --mysql默认是1
set @@autocommit=0; --设置自动提交事务参数为0,表示手动提交事务;
2)提交事务:
commit;
3)回滚事务
rollback;
打开一个连接
select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.01 sec)--查询事务自动提交设置,默认是自动提交
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)--设置事务自动提交设置为0,此时需要手动提交事务
mysql> set @@autocommit=0;
Query OK, 0 rows affected (0.00 sec)mysql> select @@zutocommit;
ERROR 1193 (HY000): Unknown system variable 'zutocommit'
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            0 |
+--------------+
1 row in set (0.00 sec)--更新数据后,事务没有提交,其他用户不能看到该用户的操作
mysql> update account set money=money+1000 where name='张三';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> update account set money=money-1000 where name='李四';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  3000 |
|  2 | 李四   |  1000 |
+----+--------+-------+
2 rows in set (0.00 sec)--手动提交事务,另外的用户,可以看到该用户对数据的变更
mysql> commit;
Query OK, 0 rows affected (0.01 sec)mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  3000 |
|  2 | 李四   |  1000 |
+----+--------+-------+
2 rows in set (0.00 sec)打开另外一个连接
mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  3000 |
|  2 | 李四   |  1000 |
+----+--------+-------+
2 rows in set (0.00 sec)
方式二:
1)开启事务
start transaction 或 begin --手动开启事务
2)提交事务
commit;
3)回滚事务
rollback;
--重新设置自动提交
mysql> set-> @@autocommit =1;
Query OK, 0 rows affected (0.01 sec)mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)--使用begin手动开启事务,开启事务后,需要手动提交mysql> begin-> ;
Query OK, 0 rows affected (0.00 sec)--修改数据后,不执行commit,其它session不能看到该事务对数据的改变
mysql> update set money =2000;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'set money =2000' at line 1
mysql> update account set money =2000;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)--执行commit之后,事务提交,其他session可以看到该事务的数据变更
mysql> commit;
Query OK, 0 rows affected (0.01 sec)另外一个连接
--另外一个事务没有执行commit,该session不能看到其他事务对数据的改变
mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  3000 |
|  2 | 李四   |  1000 |
+----+--------+-------+
2 rows in set (0.00 sec)mysql> 
mysql> 
mysql> 
--其他事务执行了commit操作,该事务可以看到数据变更
mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)3、事务的四大特性(ACID)
原子性(Automicity):事务是不可分割的细小单元,要么全部成功,要么全部失败。
一致性(Consistency):事务完成时,必须使所有的数据保持状态一致。
隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
持久性(Duration):事务一旦提交或回滚,它对数据库中数据的改变就是永久的。
4、并发事务问题:
| 问题 | 描述 | 
| 脏读 | 一个事务读取到另一个事务还没有提交的数据 | 
| 不可重复读 | 一个事务先后读取同一条记录,两次读取的结果不同,称为不可重复读 | 
| 幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了”幻影“ | 
5、事务隔离级别
为了解决并发事务问题,引入事务隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 
| read uncommited | 有 | 有 | 有 | 
| read commited | 无 | 有 | 有 | 
| reapeatable read(mysql默认) | 无 | 无 | 有 | 
| serializable | 无 | 无 | 无 | 
--查看系统的事务隔离级别:select @@transaction_isolation--设置事务隔离级别SET [SESSION|GLOBAL] TRANSATION ISOLATION LEVEL [READ UNCOMMITED|READ COMMITED|REPEATABLE READ|SERIALIZABLE]