【Mysql】基础(函数,约束,多表查询,事务)
Mysql基础
1. 函数
1.1 字符串函数
字符串索引从1开始,用substring时注意。
select concat('java', 'mysql');
select lower('HELLO');
select upper('hello');
select lpad('he', 5, '0');
select rpad('he', 5, '0');
select trim(' hello mysql ');
select substring('hellomysql', 1, 3);
1.2 数值函数
select ceil(1.1);
select floor(11.1);
select mod(3, 4);
select rand();
select round(2.345, 2);
1.3 日期函数
select curdate();
select curtime();
select now();
select year(now());
select month(now());
select day(now());
select date_add(now(), interval 70 year);
select datediff('2025-03-30', '2005-02-20');
1.4 流程函数
2. 约束
约束是作用于表中字段上的规则,用于限制存储在表中的数据。
create table user(
id int primary key auto_increment comment '主键',
name varchar(10) not null unique,
age int check(age > 0 and age <= 120),
status char(1) default '1',
gender char(1)
) comment '用户表';
- 外键约束
外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。
- 创建语法
create table 表名(
字段名 数据类型,
...
[constraint] [外键名称] foreign key(外键字段名) references 主表(主表列名)
);
alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名);
- 删除外键
alter table 表名 drop foreign key 外键名称;
- 删除更新行为
alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名) on update cascade on delete cascade;
3. 多表查询
3.1 多表关系
-
一对多(多对一)
-
多对多
-
一对一
3.2 多表查询概述
指从多张表中查询数据,多表查询时要消除无效的笛卡尔积。
多表查询的分类:
-
连接查询
- 内连接:相当于查询A,B交集部分数据。
- 外连接:
- 左外连接:查询左表所有数据,以及两张表交集部分数据。
- 右外连接:查询右表所有数据,以及两张表交集部分数据。
- 自连接:当前表与自身的连接查询,自连接必须使用表别名。
-
子查询
3.3 内连接
找A,B的交集。
隐式内连接:select 字段列表 from 表1, 表2 where 条件... ;
显示内连接:select 字段列表 from 表1 [inner] join 表2 on 连接条件... ;
隐式内连接:
create table emp(
id int auto_increment primary key comment '主键id',
name varchar(10) comment '姓名',
age int check ( age > 0 and age <= 120 ) comment '年龄',
salary int comment '工资',
dept_id int comment '外键部门id',
constraint fk_emp_dept foreign key (dept_id) references dept (id)
) comment '员工表';
insert into emp (name, age, salary, dept_id) values ('李华', 18, 2000, 2),
('张三丰', 35, 20000, 3),
('王爽', 23, 5000, 1), ('王伟栋', 26, 30000, 1);
create table dept(
id int auto_increment primary key comment '主键id',
name varchar(10) unique
) comment '部门';
insert into dept (name) values ('市场部'), ('销售部'), ('技术部');
select * from emp, dept where emp.dept_id = dept.id;
显示内连接:
select * from emp inner join dept on emp.dept_id = dept.id;
3.4 外连接
左外连接:select 字段列表 from 表1 left [outer] join 表2 on 条件;
右外连接:select 字段列表 from 表1 right [outer] join 表2 on 条件;
insert into emp(id, name, age, salary, dept_id) values (null, '伊达', 20, 50000, null);
insert into dept(id, name) values (null, '宣传部');
select * from emp left outer join dept on emp.dept_id = dept.id;
select * from emp right outer join dept on emp.dept_id = dept.id;
右外连接可以改写为左外连接。对于内连接和外连接查询的是什么,我们不妨用集合的思想去考虑。
3.5 自连接
select 字段列表 from 表A 别名A join 表A 别名B on 条件...;
自连接既可以是内连接也可以是外连接查询。
select a.name as '员工', b.name as '领导' from emp as a, emp as b where a.manager_id = b.id;
自连接可看成两张表。自连接表必须起别名。
自连接的左外连接:
select a.name as '员工', b.name as '领导' from emp a left join emp b on a.manager_id = b.id;
3.6 联合查询
对于联合查询union,就是把多次查询的结果合并起来,形成一个新的查询结果集。
select 字段列表 from 表A...
union[all]
select 字段列表 from 表B...;
select * from emp where salary <= 5000
union all
select * from emp where age >= 20;
select * from emp where salary <= 5000
union
select * from emp where age >= 20;
union all是直接将查询的结果合并;而union是将查询的结果合并然后去重。
可以合并的条件:查询的多张表的列数必须相同,也就是字段相同。
3.7 子查询
sql语句中嵌套select语句,称为嵌套查询,又称子查询。
子查询外部的语句可以是insert/update/delete/select的任何一个。
根据子查询的结果不同,分为:
- 标量子查询:子查询结果为单个值。
- 列子查询:子查询结果为一列。
- 行子查询:子查询结果为一行。
- 表子查询:子查询结果为多行多列。
3.7.1 标量子查询
select name from emp where emp.dept_id = (select id from dept where name = '销售部');
3.7.2 列子查询
常用的操作符:in, not in, any, some, all
select * from emp where dept_id in (select id from dept where name = '市场部' or name = '技术部');
select * from emp where salary > all ( select salary from emp where dept_id = (select id from dept where name = '市场部') );
select * from emp where salary > any (select salary from emp where dept_id = (select id from dept where name = '市场部'));
3.7.3 行子查询
select * from emp where (salary, manager_id) = (select salary, manager_id from emp where name = '伊达');
3.7.4 表子查询
4. 事务
4.1 事务的概念
事务是一组操作集合,它是一个不可分割的工作单位,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
4.2 事务的操作
查看/设置事务提交方式
select @@autocommit;
set @@autocommit = 0;
提交事务
commit;
回滚事务
rollback;
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
程序抛出异常
update account set money = money + 1000 where name = '李四';
commit ;
rollback;
开启事务
start transaction 或 begin;
提交事务
commit;
回滚事务
rollback;
start transaction ;
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
程序抛出异常
update account set money = money + 1000 where name = '李四';
commit ;
rollback;
4.3 事务的四大特性(ACID)
- 原子性:事务是不可分隔的最小操作单元,要么全部成功,要么全部失败。
- 一致性:事务完成时,必须使所有的数据都保持一致状态。
- 隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
4.4 并发事务问题
- 脏读
- 不可重复读
- 幻读
4.5 事务的隔离级别
查看事务的隔离级别
英语单词:transaction事务,isolation隔离
select @@transaction_isolation;
设置事务的隔离级别
set [session|global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable}
session当前会话