一、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]