4. 约束
概念:对表中的数据进行限定,保证数据的正确性,有效性和完整性。比如:非空
分类:1. 主键约束:primary key
1. 注意
1. 含义:非空且唯一
2. 一张表只有一个字段是主键
3. 主键就是表中记录的唯一标识
create table stu(
id int primary key, -- 添加主键约束
own_name varchar(20) not null
);
2. 删除主键:
ALTER TABLE stu DROP PRIMARY KEY;
3. 创建完表之后添加主键
alter table [表名] modify [列名] [类型] PRIMARY KEY;
4. 自动增长:
概念,如果某一列是数值类型的,使用auto_increment 可以来完成值的自动增长, 一般可以配合int 类型的主键来用,比较方便
自动增长删除:
alter table [表名] modify id int;
alter table [表名] modify [列名] int auto_increment;
2. 非空约束: not null
not null
* 添加方式在创建表时添加
create table stu(
id int,
own_name varchar(20) not null
);
* 添加非空约束 alter table [表名] change [原列名] [新列名] [数据类型];
* 删除非空约束
alter table [表名] modify [列名] [类型];
3. 唯一约束:unique
表示值不可以重复
删除唯一约束
alter table [表名] drop indx [列名];
添加唯一约束
alter table [表名] modify [列名] [类型] unique;
*注意 unique虽然表示唯一,但是允许多个null
4. 外键约束:foreign key
1. 创建表时,可以添加外键
create table [表名]{
...
constraint [外键名称] foreign key [本表关联的列名称] references 主表名称(主表列名称)
}
例如:
CREATE TABLE department(
id INT PRIMARY KEY AUTO_INCREMENT,
dep_name VARCHAR(20),
dep_location VARCHAR(50)
);
CREATE TABLE employee(
id INT PRIMARY KEY AUTO_INCREMENT,
e_name VARCHAR(20),
age INT,
dep_id INT,
CONSTRAINT emp_dep_fy FOREIGN KEY (dep_id) REFERENCES department(id)
);
删除外键:
alter table [表名] drop foreign key [外键名];
表创建后添加外键
alter table [表名] add constraint [外键名称] foreign key ([本表关联的列名称]) references 主表名称([主表列名称])
级联操作
添加级联更新操作:
alter table [表名] add constraint [外键名称] foreign key ([本表关联的列名称]) references 主表名称([主表列名称]) on update cascade;
添加级联删除操作:
alter table [表名] add constraint [外键名称] foreign key ([本表关联的列名称]) references 主表名称([主表列名称]) on delete cascade;
5. 多表之间的关系
1. 一对一关系(真正的开发中一对一的关系,较少)
一个人身份证号是唯一的,一个身份证号对应一个特定的人
实现方式:可以在任意一方的添加外键指向另一方的主键
且外键唯一
2. 一对多(多对一)
一个班级多个学生,一个学生只能在一个班级
实现方式:多的一方建立外键,指向一的一方的主键
3. 多对多
一个学生可以选多门课程,一个课程可以有很多学生选择
实现方式:中间表 课程该表至少包含两个字段,
这两个字段作为中间表的外键,分别指向学生表和课程表的主键
4. 实现关系
demo:
CREATE TABLE tab_category(
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(100) NOT NULL UNIQUE
);
CREATE TABLE tab_route(
rid INT PRIMARY KEY AUTO_INCREMENT,
rname VARCHAR(100) NOT NULL UNIQUE,
price DOUBLE,
rdate DATE,
CONSTRAINT route_category FOREIGN KEY(rid) REFERENCES tab_category(cid)
);
CREATE TABLE tab_user(
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) UNIQUE NOT NULL,
passwords VARCHAR(20) NOT NULL,
birth DATE,
sex CHAR(1) DEFAULT '男',
telephont VARCHAR(30),
email VARCHAR(100)
);
CREATE TABLE tab_favorite(
rid INT,
rdate DATETIME,
uid INT,
-- 创建复合主键 这两个列共同组成表的主键
PRIMARY KEY(rid, uid),
FOREIGN KEY(rid) REFERENCES tab_route(rid),
FOREIGN KEY(uid) REFERENCES tab_user(uid)
);
6. 范式(表的设计准则)
设计数据库时要遵循的规范, 要遵循后面的范式,必须遵守前面所有范式的要求
分类:
1. 第一范式(1NF):没一列都是不可分割的原子数据项
2. 第二范式(2NF):在1NF的基础上非码属性必须完全依赖于候选码(在1NF的基础上
消除非主属性对主码的部分函数依赖)
函数依赖,如果 A属性(或属性组) 可以确定唯一的B属性的值 这就叫函数依赖(B依赖A)
完全函数依赖,如果A是一个属性组则B属性的确定需要A中所有的值
部分函数依赖,如果A是一个属性组则B属性的确定需要A中部分的值
传递函数依赖,A属性(或属性组) 确定B , B确定C 则AC构成传递依赖
码:如果一张表中,一个属性或者属性组被其他所有的属性依赖,则该属性或属性组叫做该表的码
主属性:码属性组中的所有属性
非主属性:除去码属性组中的属性
3. 第三范式(3NF):在2NF的基础上,任何主属性不依赖于其他非主属性(在2NF基础上,消除传递依赖)
7. 备份和还原
1. 命令行方式
备份:mysqldump -u[用户名] -p[密码] [数据库名称] > [保存路径]
mysqldump -uroot -p**** mydb1 > d://test.sql
还原:1. 登录数据库
2. 创建数据库
3. 使用数据库
4. 执行文件 source [备份的文件路径s]
2. 图形化工具的方式:
备份:右键就可以了
还原:创建数据库,执行SQL脚本
8. 多表查询
select * from [表1], [表2]; -- 笛卡尔积
得到所有数据的组合,这时难免会有一些无用的数据
我们来去除一下
* 内连接查询
1. 隐式内连接
使用where消除无用数据
SELECT * FROM [表1], [表2] WHERE [表1].`属性` = [表2].`属性`;
SELECT emp.`name`, emp.`salary`, dept.`name` FROM emp, dept WHERE emp.`dept_id` = dept.`id`;
我们还可以给表起一个别名:
SELECT
t1.`name`, t1.`salary`, t2.`name`
FROM
emp t1, dept t2 -- 起别名
WHERE
t1.`dept_id` = t2.`id`
2. 显式内连接
select [字段列表] from [表名1] (inner) join [表名2] on 条件; -- inner 可以省略的
注意事项,
从哪些表中查
条件是什么
查询哪些字段
* 外连接查询
左外连接:
select [字段列表] from [表1] left (outer) join [表2] on 条件;
查询的是表1的所有记录和表1表2的交集
右外连接:
select [字段列表] from [表1] right (outer) join [表2] on 条件;
查询的是表2的所有记录和表1表2的交集
* 子查询
概念:查询中嵌套查询, 则嵌套的那个为子查询
1. 子查询的结果是单行单列:比如员工表中查询工资最高的是谁
step1. 先使用max聚合函数查除最高的工资
step2. 再根据这个工资找到员工
其实通过子查询可以让这两步变为一步
select # from emp where emp.salary = (select max(salary) from emp);
结论:作为条件 <, > = ...
2. 子查询的结果是多行单列使用运算符in
问题:查询"财务部" 和 "市场部"中的员工
select # from emp where emp.dept_id in (select id from dept where id = 2 or id = 3);
3. 子查询的结果是多行多列
查询结果当作表 这个表叫做虚拟表
SELECT
*
FROM
dept t1,
(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
WHERE
t1.id = t2.dept_id;
9. 事物
1. 基本介绍
事物:如果一个包含多个步骤的业务操作被事物管理,那么这些操作要么同时成功
要么同时失败
操作:
1. 开启事物: start transaction;
2. 回滚:rollback;
3. 提交:commit
使用实例:
-- 开启事物
START TRANSACTION
-- zhangsan -500
UPDATE account SET balance = balance - 500 WHERE NAME = "zhangsan";
-- lisi +500`account`
UPDATE account SET balance = balance + 500 WHERE NAME = "lisi";
-- 没有问题就提交事务
COMMIT;
-- 出问题了就回滚
ROLLBACK;
2. 四大特征
1. 原子性:不可分割的最小操作单位,要么同时成功,要么同时失败
2. 持久性:提交或者回滚后,数据库会持久化保存数据
3. 隔离性:多个事务之间,相互影响,但我们需要它独立
4. 一致性:事务操作前后,数据总量不变
3. 事物的隔离级别
多个事务操作同一批数据,就会引发一些问题,设置不同的隔离级别就可以解决这个问题。
存在的问题:
1. 脏读:一个事务读取到另一个食物中没有提交的数据
2. 不可重复读:
3. 幻读
4. mysql 每一条DML都当作一条事务
修改默认提交方式:set @@autocommit = 0;
![](https://img2024.cnblogs.com/blog/35695/202408/35695-20240826070647288-243310440.jpg)