范式: 设计数据库表的规则
第一范式:
每一列不能再拆分,查询出的结果不需要进一步处理,可以直接使用
第二范式:
每张数据库表必须要有主键
可以解决数据冗余(重复)问题 (一张表只能描述一件事情)
第三范式
从表的外键必须使用主表的主键
单表查询: select * from 表名;
多表查询: select * from 表1,表2,表3… ;
建表语句:
-- 创建部门表
CREATE TABLE dept (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部'),('销售部');
-- 创建员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(10), -- 员工姓名
gender CHAR(1), -- 性别
salary DOUBLE, -- 工资
join_date DATE, -- 入职日期
dept_id INT, -- 所属部门id (外键字段)
FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键约束
);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('沙僧','男',6666,'2013-02-24',NULL);
格式: select * from 表1,表2…;
产生笛卡尔积
隐式内连接: ★★★
select * from 表1,表2 where 条件;
显示内连接
select * from 表1 [inner] join 表2 on 关联条件 where 筛选条件;
on: 后跟的两个表的关联条件
where: 后跟的是对结果的筛选条件
- 1.查询唐僧的信息,显示员工id,姓名,性别,工资和所在的部门名称
-- 内连接查询-隐式内连接
# a.确定要查询的表 emp dept
SELECT * FROM emp,dept;
# b.找两张表的关联条件 emp.dept_id = dept.id
SELECT * FROM emp,dept WHERE emp.dept_id = dept.id;
# c.确定要查询的结果数据
SELECT e.id,e.name,e.gender,e.salary,d.name AS "部门名称"
FROM emp AS e,dept AS d
WHERE e.dept_id = d.id AND e.name='唐僧';
-- 内连接查询-显式内连接
# a.确定要查询的表 emp dept
SELECT * FROM emp INNER JOIN dept;
# b.找两张表的关联条件 emp.dept_id = dept.id
SELECT *
FROM emp INNER JOIN dept
ON emp.dept_id = dept.id;
# c.确定要查询的结果数据
SELECT e.id,e.name,e.gender,e.salary,d.name AS "部门名称"
FROM emp AS e INNER JOIN dept d
ON e.dept_id = d.id
WHERE e.name='唐僧';
左外连接: 以join左边的表为主,查询其所有数据信息,根据条件查询join右边的表,将满足条件的数据查询出来,如果没有满足条件的数据,则填充null
select * from 表1 left [outer] join 表2 on 关联条件 where 筛选条件;
右外连接: 以join右边的表为主,查询其所有数据信息,根据条件查询join左边的表,将满足条件的数据查询出来,如果没有满足条件的数据,则填充null
select * from 表1 rigth [outer] join 表2 on 关联条件 where 筛选条件;
-- 2.查询所有员工及所属部门
SELECT *
FROM emp LEFT OUTER JOIN dept
ON emp.dept_id=dept.id;
SELECT * FROM dept RIGHT OUTER JOIN emp
ON emp.dept_id=dept.id;
-- 3.查询所有部门及所含员工
SELECT * FROM dept LEFT JOIN emp
ON emp.dept_id=dept.id;
SELECT * FROM emp RIGHT JOIN dept
ON emp.dept_id=dept.id;
概念:
一条sql执行的结果是另一条sql的条件
子查询结果:
单一结果(单行单列): select * from 表名 where (= 子查询结果)
单列多值(多行单列): select * from 表名 where (in 子查询结果)
多列多值(多行多列): select * from (子查询结果) as 别名 where …
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败
转账案例:
tom 给 rose转账(100元)
account: 账户表
name money
tom 1000
rose 1000
从tom帐号上减100元
update account set money = money - 100 where name = ‘tom’;
给rose帐号上加100元
update account set money = money + 100 where name = ‘rose’;
mysql的事务控制是自动的,默认一条sql就是一个事务:
mysql的事务控制是自动的: sql语句执行完毕后,mysql会自动将事务提交.
每条sql语句执行完毕后,立即将执行结果写入到数据库中
查看mysql的事务提交状态:
show variables like ‘%commit%’;
开启手动事务(关闭自动事务提交)
set autocommit = 0;
关闭mysql手动事务(开启自动事务提交)
set autocommit = 1;
start transaction; | begin; 开启手动事务控制
commit; 提交事务(将事务中的sql语句执行结果保存到数据库中)
rollback; 回滚事务(回到事务开启前的状态)
了解: 设置事务的回滚点
savepoint 名称;
1000操作 1 2 3…100(“设置回滚点”)…200(“设置回滚点”)…900(“设置回滚点”)…999(失败)
rollback to 名称; 回到指定的回滚点上
让tom给rose转账:
每次转100元,转5次
在第2次执行完毕后,设置回滚点.
在第4次执行完毕后,设置回滚点.
事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
事务前后数据的完整性必须保持一致
是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离,不能相互影响。
指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
1.将隔离级别调到最低
show variables like "%isolation%"; -- 查询mysql的隔离级别
set global transaction isolation level read uncommitted; -- 设置成功后,需要重启mysql
一个事务读取到了另一个事务中尚未提交的数据
一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致的,这是事务update时引发的问题
一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的,这是insert或delete时引发的问题
set global transaction isolation level 级别字符串;
read uncommitted:
脏读: 读未提交
不可重复读: 多次读取到的数据不一致.(update)
幻读: 一个事务读取到了另外一个事务添加后删除的数据
read committed
只能解决脏读问题
repeatable read
使用serializable隔离级别,一个事务没有执行完,其他事务的SQL执行不了,可以挡住幻读
serializable
查询mysql的隔离级别:
show variables like "%isolation%"; // REPEATABLE-READ
多表和单表练习