数据库表的约束

主键约束

约束名 约束关键字
主键 primary key
唯一 unique
非空 not null
外键 foreign key
检查约束 check 注:mysql 不支持
  • 非空
  • 唯一

通常不用业务字段作为主键,单独给每张表设计一个 id 的字段,把 id 作为主键。主键是给数据库和程序使用的,不是给最终的客户使用的。所以主键有没有含义没有关系,只要不重复,非空就行。

  1. #创建表学生表 st5, 包含字段(id, name, age)将 id 做为主键
  2. create table st5(
  3. id int primary key, #给id字添加了一个约束
  4. name VARCHAR(20),
  5. age int
  6. )
  7. desc st5;
# 在已有表中添加主键约束
alter table st5 add primary key(id);
#插入重复的主键值
insert into st5 values (1,'关羽',30);
#1062 - Duplicate entry '1' for key 
insert into st5 values (1,'关云长',20)

select * from st5

#插入 NULL 的主键值, Column 'id' cannot be null 
insert into st5 values(null,'赵云',20);

#删除 st5 表的主键约束
alter table st5 drop primary key;
#只能删除唯一约束,不能删除不为空约束

主键自增

AUTO_INCREMENT 表示自动增长(字段类型必须是整数类型)

#指定起始值为 1000 
create table st4 (
id int primary key auto_increment, 
name varchar(20)
) auto_increment = 1000;
insert into st4 values (null,'孔明');

select *  from st4;

#创建好以后修改起始值
alter table st4 auto_increment = 2000;
#delete 删除所有记录之后,自增长无影响
delete from st4;

#truncate : 删除以后,自增长又重新开始
TRUNCATE table st4;
  • delete 删除所有记录之后,自增长无影响

  • truncate : 删除以后,自增长又重新开始

主键自增不能插入空值
lQLPJxZt_Q2mnw3NARTNAVWw6AdQ_xFYaDECtUV9hwC8AA_341_276.png
可以在软件中设置自动递增也可以手动修改
lQLPJxZt_TuL5k7NAZ_NAy2wAtJpsTzXMFACtUXJNMDhAA_813_415.png

唯一约束

#唯一约束
#创建学Th表 st7, 包含字段(id, name),name 这一列设置唯一约束,不能出现同名的学Th 
create table st7 (
id int,
name varchar(20) unique
)
#添加一个同名的学Th
insert into st7 values (1, '张三');

select * from st7;
-- Duplicate entry '张三' for key 'name' 
insert into st7 values (2, '张三');

#重复插入多个 null 会怎样?
insert into st7 values (2, null);

insert into st7 values (3, null);
  • null值可以重复
  • image.png
  • 记录不能相同
  • image.png ```sql

    为已将创建的表添加唯一约束

    alter table st7 add unique(name);

desc st7;

删除st7表的唯一约束[通过删除唯一索引来实现删除唯一约束]

alter table st7 drop index hrj;

索引名是什么就删除什么

- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22850648/1655967316724-e67a4255-17b9-46e0-9723-dbe983d64ea0.png#clientId=u93a188dd-b685-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=132&id=u14c648d0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=165&originWidth=375&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8090&status=done&style=none&taskId=uad7303fd-c42c-45e4-b6d8-75fcc55f812&title=&width=300)
<a name="zKc77"></a>
### 非空约束
```sql
# 非空约束
#创建表学Th表 st8, 包含字段(id,name,gender)其中 name 不能为 NULL 
create table st8 (
id int,
name varchar(20) not null, 
gender char(1)
)
#Column count doesn`t match value count at row 1
insert into st8 values (2, null);

#添加一条记录其中姓名不赋值
insert into st8 values (1,'张三风','男');
#Column 'name' cannot be null
insert into st8 values (2,null,'男');

非空唯一约束

与主键约束的区别:

  • 主键数在一个表中,只能有一个。不能出现多个主键。主键可以单列,也可以是多列。
  • 自增长只能用在主键上
  • 主键约束在一张表中只能有一个,但是not null unique就受限制了.可以出现很多个

    create table st7 (
    id int,
    name varchar(20) not null unique
    )
    

    默认值

    ```sql

    创建一个学Th表 st9,包含字段(id,name,address), 地址默认值是广州

    create table st9 ( id int, name varchar(20), address varchar(20) default ‘广州’ )

添加一条记录,使用默认地址

insert into st9 values (1,’李白’,DEFAULT);

select * from st9;

insert into st9(id,name) values (2,’张三’);

添加一条记录,不使用默认地址

insert into st9 values(3,’李四光’,’深圳’);

insert into st9(id,address) values(5,’深圳’);

<a name="Ees5A"></a>
### 外键约束
```sql
#外键约束
#创建一个员工表包含如下列(id, name, age, dep_name, dep_location),id 主键并自动增长,添加 5 条数
CREATE TABLE emp2 (
id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(30),
age INT,
dep_name VARCHAR(30), dep_location VARCHAR(30)
);
-- 添加数据
INSERT INTO emp2 (NAME, age, dep_name, dep_location) VALUES ('张三', 20, '研发部', '广州'); 
INSERT INTO emp2 (NAME, age, dep_name, dep_location) VALUES ('李四', 21, '研发部', '广州'); 
INSERT INTO emp2 (NAME, age, dep_name, dep_location) VALUES ('王五', 20, '研发部', '广州');

INSERT INTO emp2 (NAME, age, dep_name, dep_location) VALUES ('老王', 20, '销售部', '深圳'); 
INSERT INTO emp2 (NAME, age, dep_name, dep_location) VALUES ('大王', 22, '销售部', '深圳'); 
INSERT INTO emp2 (NAME, age, dep_name, dep_location) VALUES ('小王', 18, '销售部', '深圳');

以上数据存在大量冗余image.png

解决方案

# 创建部门表(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    -- 外键对应主表的主键
-- 创建外键约束
constraint emp_depid_fk foreign key (dep_id) references department(id)
)

-- 添加 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);
#插入一个dep_id有问题的值
insert into employee values (null,'老张', 19,6);
delete from employee where id =  9 ;

#需要进行外键约束 ,保证dep_id只有部门表的数据

#已有的表增加外键约束

alter table employee add CONSTRAINT emp_dept_dept_id_fk foreign key (dep_id) REFERENCES department(id); 

#删除外键约束
alter table employee drop foreign key emp_dept_dept_id_fk;

select * from employee;

desc employee;

image.png
表的关系
lQLPJxZuJE00svLNAdnNAxWw0gNw65At4QcCtYXL3ICvAA_789_473.png

级联(少用,了解就行)

#外键的级联(关联)
select * from employee;

select * from department;

-- 要把部门表中的 id 值 2,改成 5,能不能直接更新呢?
-- Cannot delete or update a parent row: a foreign key constraint fails 
update department set id=5 where id=2;

-- 要删除部门 id 等于 1 的部门, 能不能直接删除呢?
-- Cannot delete or update a parent row: a foreign key constraint fails 
delete from department where id=1;

在navict中设置级联
lQLPJxZuKM6OQ0TNASfNAqCwRb3y7kLE0BYCtY0tTsAZAA_672_295.png

#级联操作(少用,了解就行)
#级联更新
update department set id = 5 where dep_name = '销售部';
#级联删除
delete from department where id=1;

检查约束

#检查约束check
#mysql不支持check 但是其他数据库支持
create table st10 ( 
id int,
name varchar(20),
sex char(1) check(sex = '男' or sex = '女')
)

insert into st10 values (1,'小李','♀');

mysql不支持
设置完成后只能插入对应的值,

数据约束小结

约束名 关键字 说明
主键 primary key 1) 唯一
2) 非空
默认 default 如果一列没有值,使用默认值
非空 not null 这一列必须有值
唯一 unique 这一列不能有重复值
非空唯一 not null unique 这一列必须有值 这一列不能有重复值
外键 foreign key 主表中主键列,在从表中外键列
检查 check 只能插入设置的值