MySQL基础:数据库表的约束

目录

数据库表的约束

数据库约束的概述

约束的作用

约束种类

主键约束

主键的作用

​哪个字段应该作为表的主键? 

创建主键

删除主键

主键自增

修改自增长的默认值起始值

DELETE 和 TRUNCATE 对自增长的影响

唯一约束

唯一约束的基本格式

非空约束

非空约束的基本语法格式

默认值

外键约束

什么是外键约束

创建约束的语法

删除外键

外键的级联

数据约束小结


数据库表的约束

数据库约束的概述

约束的作用

  • 对表中的数据进行限制,保证数据正确性、有效性和完整性
  • 一个表如果添加了约束,不正确的数据将无法插入到表中
  • 约束在创建表的时候添加比较合适

约束种类

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

主键约束

主键的作用

  • 用来唯一标识数据库中的每一条记录


哪个字段应该作为表的主键? 

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

创建主键

  • 主键关键字: primary key
  • 主键的特点:
    • 1) 非空 not null
    • 2) 唯一
  • 在创建表的时候给字段添加主键
字段名 字段类型 PRIMARY KEY
  • 在已有表中添加主键
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
-- 创建表学生表 st5, 包含字段(id, name, age)将 id 做为主键
create table st5 (
 id int primary key, -- id 为主键
 name varchar(20),
 age int
)
desc st5;

删除主键

-- 删除 st5 表的主键
alter table st5 drop primary key;
-- 添加主键
alter table st5 add primary key(id);

主键自增

  • 主键如果让我们自己添加很有可能重复,我们通常希望在每次插入新记录时,数据库自动生成主键字段的值
AUTO_INCREMENT 表示自动增长(字段类型必须是整数类型)

修改自增长的默认值起始值

  • 默认地 AUTO_INCREMENT 的开始值是 1,如果希望修改起始值,请使用下列 SQL 语法
  • 创建表时指定起始值
CREATE TABLE 表名(
列名 int primary key AUTO_INCREMENT
) 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;
insert into st4 values (null, '刘备');

DELETE 和 TRUNCATE 对自增长的影响

  • DELETE:删除所有的记录之后,自增长没有影响。

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

唯一约束

  • 什么是唯一约束: 表中某一列不能出现重复的值

唯一约束的基本格式

字段名 字段类型 UNIQUE
  • 实现唯一约束
-- 创建学生表 st7, 包含字段(id, name),name 这一列设置唯一约束,不能出现同名的学生
create table st7 (
 id int,
 name varchar(20) unique
)
-- 添加一个同名的学生
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 没有数据,不存在重复的问题

非空约束

  • 什么是非空约束:某一列不能为 null

非空约束的基本语法格式

-- 创建表学生表 st8, 包含字段(id,name,gender)其中 name 不能为 NULL
create table st8 (
id int,
name varchar(20) not null,
gender char(1)
)
-- 添加一条记录其中姓名不赋值
insert into st8 values (1,'张三疯','男');
select * from st8;
-- Column 'name' cannot be null
insert into st8 values (2,null,'男');

默认值

  • 什么是默认值:
字段名 字段类型 DEFAULT 默认值
-- 创建一个学生表 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, '李四光', '深圳');
  • 疑问:如果一个字段设置了非空与唯一约束,该字段与主键的区别?
    • 主键数在一个表中,只能有一个。不能出现多个主键。
    • 主键可以单列,也可以是多列。
    • 自增长只能用在主键上

外键约束

  • 单表的缺点
    • 创建一个员工表包含如下列(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, '销售部', '深圳');
  • 以上数据表的缺点:
    •  数据冗余
    • 后期还会出现增删改的问题

  • 解决方案

-- 解决方案:分成 2 张表
-- 创建部门表(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);
select * from employee;
  • 问题:当我们在 employee 的 dep_id 里面输入不存在的部门,数据依然可以添加.但是并没有对应的部门,实际应用中不能出现这种情况。employee 的 dep_id 中的数据只能是 department 表中存在的 id

  • 目标: 需要约束 dep_id 只能是 department 表中已经存在 id
  • 解决方式: 使用外键约束

什么是外键约束

  • 什么是外键:在从表中与主表主键对应的那一列,如:员工表中的 dep_id
    • 主表: 一方,用来约束别人的表
    • 从表: 多方,被别人约束的表

创建约束的语法

  • 新建表时增加外键:
[CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名)
  • 已有表增加外键:
ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主键字段名);
  • 具体操作:
-- 1) 删除副表/从表 employee
drop table employee;
-- 2) 创建从表 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)
)
-- 3) 正常添加数据
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);
select * from employee;
-- 4) 部门错误的数据添加失败
-- 插入不存在的部门
-- Cannot add or update a child row: a foreign key constraint fails
INSERT INTO employee (NAME, age, dep_id) VALUES ('老张', 18, 6);

删除外键

ALTER TABLE 从表 drop foreign key 外键名称;
-- 删除 employee 表的 emp_depid_fk 外键
alter table employee drop foreign key emp_depid_fk;
-- 在 employee 表情存在的情况下添加外键
alter table employee add constraint emp_depid_fk foreign key (dep_id) references department(id);

外键的级联

  • 出现新的问题:
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;
  • 什么是级联操作:
    • 在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操作
级联操作语法描述
ON UPDATE CASCADE级联更新,只能是创建表的时候创建级联关系。更新主表中的主键,从表中的外键列也自动同步更新
ON DELETE CASCADE级联删除
-- 删除 employee 表,重新创建 employee 表,添加级联更新和级联删除
drop table employee;
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
)
-- 再次添加数据到员工表和部门表
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);
-- 删除部门表?能不能直接删除?
drop table department;
-- 把部门表中 id 等于 1 的部门改成 id 等于 10
update department set id=10 where id=1;
select * from employee;
select * from department;
-- 删除部门号是 2 的部门
delete from department where id=2;

数据约束小结

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

【注】参考黑马MySQL教程

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页