1 约束的作用:对表中数据进行限制,保证数据的正确性,有效性和完整性。一个表要是添加了约束,不正确的数据将无法添加。约束一般在建表时添加。
2 约束种类:
约束类型 | 作用 |
---|---|
primary key | 主键 |
unique | 唯一 |
not null | 非空 |
foreign key | 外键 |
check | 检查约束 |
3 主键作用:
用来唯一标识数据库的每一条记录。
4 哪个字段应该作为主键
1 通常不用业务字段作为主键,单独给每张表设计一个id.主键是给数据库和程序使用的,不是给最终的客户使用的。所以主键有没有含义没有关系,只要不重复,非空就行。
如:身份证,学号不建议做成主键
主键特点:非空,唯一
例句:建表时添加主键
create table stu (
id int primary key, -- id 为主键
name varchar(20),
age int
)
5 主键自增。
每次自己添加主键,可能造成重复。所以可以使数据库在添加数据时自动生成主键值
AUTO_INCREMENT 表示自动增长(字段类型必须是整数类型)
默认主键起始值1,例句:
CREATE TABLE 表名(
列名 int primary key AUTO_INCREMENT
) AUTO_INCREMENT=起始值;
6 唯一约束
设置唯一约束,该字段不能重名
7 非空约束:某一列不能为null.
8 默认值:字段名 字段类型 DEFAULT 默认值
例句:
create table stu (
id int,
name varchar(20),
address varchar(20) default '广州'
)
9 外键约束
1 单表的缺点
创建一个员工表包含如下列(id, name, age, dep_name, dep_location),id 主键并自动增长,添加 5 条数据
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30),
age INT,
dep_name VARCHAR(30),
dep_location VARCHAR(30)
);
-- 添加数据
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('张三', 20, '研发部', '广州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('李四', 21, '研发部', '广州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('王五', 20, '研发部', '广州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('老王', 20, '销售部', '深圳');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('大王', 22, '销售部', '深圳');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('小王', 18, '销售部', '深圳');
缺点:数据冗余,后期删改问题
解决方案:分成两种表
-- 创建部门表(id,dep_name,dep_location)
-- 一方,主表
create table department(
id int primary key auto_increment,
dep_name varchar(20),
dep_location varchar(20)
);
-- 创建员工表(id,name,age,dep_id)
-- 多方,从表
create table employee(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int -- 外键对应主表的主键
)
-- 添加 2 个部门
insert into department values(null, '研发部','广州'),(null, '销售部', '深圳');
select * from department;
-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2);
问题:当我们在 employee 的 dep_id 里面输入不存在的部门,数据依然可以添加.但是并没有对应的部门,
实际应用中不能出现这种情况。employee 的 dep_id 中的数据只能是 department 表中存在的 id
解决方案:使用外键约束
语法:
新建表时增加
[CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名)
已有表时增加
ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主
键字段名);
创建从表 employee 并添加外键约束 emp_depid_fk
-- 多方,从表
create table employee(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int, -- 外键对应主表的主键
-- 创建外键约束
constraint emp_depid_fk foreign key (dep_id) references department(id)
)
删除employee外键
-- 删除 employee 表的 emp_depid_fk 外键
alter table employee drop foreign key emp_depid_fk;
10 级联关系
问题1 :把部门表中id=2改成id=5,能不能直接更新呢?
问题2:删除部门id=1的,能直接删除吗?
什么是级联操作:在修改或者删除主表主键时,同时更新或删除副表外键值。称为级联操作
级联操作语法 | 描述 |
---|---|
on update cascade | 级联更新,只能创建表时建立级联关系。更新表中主键,从表外键同步更新 |
on delete cascade | 级联删除 |
例句:
create table employee(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int, -- 外键对应主表的主键
-- 创建外键约束
constraint emp_depid_fk foreign key (dep_id) references
department(id) on update cascade on delete cascade
)
10 表与表的关系
关系 | 举例 |
---|---|
一对多 | 部门和员工 |
多对多 | 学生和课程 |
一对一 | 比较少见,员工表,简历表 |
多对多如何建表?
例如学生和课程,用户和角色
需要创建第三张表,这张表需要至少两个字段,作为外键分别对应两张表的主键
数据库三大范式
名称 | 概念 |
---|---|
第一范式 | 数据库的每一列都是不可分割的原子项,不能是集合数组。即某个列有多个数值必须拆成多个列 |
第二范式 | 在满足第一范式的基础上表中每个字段完全依赖主键 |
第三范式 | 在满足第二范式的基础上,表中每一列都直接依赖主键,而不是通过其他列间接依赖主键 |