前言
本篇主要介绍了数据库中表字段的约束,表和表之前的关系,以及数据库设计的三大范式。
目录
一、数据库表的约束
二、表和表之间的关系
三、数据库设计的三大范式
四、总结
一、数据库表的约束
1.1 约束的作用
对表中的数据进行限制,保证数据的正确性、有效性和完整性。
一个表如果添加了约束,不正确的数据将无法插入到表中。
1.2 约束分类
约束名 | 约束关键字 |
---|---|
唯一 | unique |
非空 | not null |
外键 | foreign key |
主键 | primary key |
1.3 唯一约束
概念:
表中某一列不能出现重复的值
- 唯一约束的基本格式:
字段名 字段类型 UNIQUE
例如:
CREATE TABLE stu(
id INT,
phone_number VARCHAR(20) UNIQUE -- 手机号
);
- 删除唯一约束
ALTER TABLE 表名 DROP INDEX 字段名;
- 在表创建完后,添加唯一约束
ALTER TABLE 表名 MODIFY 字段名 VARCHAR(20) UNIQUE;
1.4 非空约束
概念:
某一列不能为 null
- 非空约束的基本语法格式
字段名 字段类型 NOT NULL
例如:
CREATE TABLE stu(
id INT,
NAME VARCHAR(20) NOT NULL -- name为非空
);
- 创建表完后,添加非空约束
ALTER TABLE 表名 MODIFY 字段名 VARCHAR(20) NOT NULL;
- 删除非空约束
ALTER TABLE 表名 MODIFY 字段名 VARCHAR(20);
如果一个字段设置了非空与唯一约束,该字段与主键的区别?
- 主键数在一个表中,只能有一个。不能出现多个主键。主键可以单列,也可以是多。
- 自增长只能用在主键上
1.5 主键约束
概念:
用来唯一标识数据库中的每一条记录
主键的特点:
- 非空且唯一
- 一张表只能有一个字段为主键
- 主键就是表中记录的唯一标识
哪个字段应该作为表的主键?
通常不用业务字段作为主键,单独给每张表设计一个 id 的字段,把 id 作为主键。主键是给数据库和程序使用的,不是给最终的客户使用的。
所以主键有没有含义没有关系,只要不重复,非空就行。
1.5.1 主键约束的语法
- 在创建表的时候给字段添加主键
字段名 字段类型 PRIMARY KEY
- 创建完表后,添加主键
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
例如:
-- 创建表学生表 st5, 包含字段(id, name, age)将 id 做为主键
CREATE TABLE student (
id INT PRIMARY KEY, -- id 为主键
name VARCHAR(20),
age INT
)
- 删除主键:
ALTER TABLE 表名 DROP PRIMARY KEY;
1.5.2 主键自增长
如果让我们自己添加主键很有可能重复,我们通常希望在每次插入新记录时,数据库自动生成主键字段的值
- 语法:
AUTO_INCREMENT 表示自动增长(字段类型必须是整数类型)
- 默认地 AUTO_INCREMENT 的开始值是 1,如果希望修改起始值,请使用下列 SQL 语法
CREATE TABLE 表名(
列名 int primary key AUTO_INCREMENT
) AUTO_INCREMENT=起始值;
- 删除自动增长
ALTER TABLE stu MODIFY id INT;
- 添加自动增长
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
DELETE 和 TRUNCATE 对自增长的影响
- DELETE:删除所有的记录之后,自增长没有影响。
- TRUNCATE:删除以后,自增长又重新开始。
1.6 外键约束
概念:
在从表中与主表主键对应的那一列
- 主表: 一方,用来约束别人的表
- 从表: 多方,被别人约束的表
1.6.1 外键约束的语法
- 新建表时增加外键
[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),
dep_id INT, -- 外键对应主表的主键
CONSTRAINT emp_depid_fk FOREIGN KEY (dep_id) REFERENCES
department(id) -- 创建外键约束
);
- 删除外键
ALTER TABLE 从表 drop foreign key 外键名称;
1.6.2 外键的级联
什么是级联操作
在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操作
级联操作语法 | 描述 |
---|---|
ON UPDATE CASCADE | 级联更新,只能是创建表的时候创建级联关系。更新主表中的主键,从表中的外键列也自动同步更新 |
ON DELETE CASCADE | 级联删除 |
例如:
CREATE TABLE employee (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
dep_id INT, -- 外键对应主表的主键
CONSTRAINT emp_depid_fk FOREIGN KEY (dep_id) REFERENCES department(id) ON UPDATE CASCADE -- 创建外键约束
)
1.7 约束小结
约束名 | 关键字 | 说明 |
---|---|---|
主键 | primary key | 1) 唯一 2) 非空 |
默认 | default | 如果一列没有值,使用默认值 |
非空 | not null | 这一列必须有值 |
唯一 | unique | 这一列不能有重复值 |
外键 | foreign key | 主表中主键列,在从表中外键列 |
二、 表与表之间的关系
一对多
最常用的关系
例如: 部门和员工
分析:一个部门有多个员工,一个员工只能对应一个部门多对多
例如:学生选课表 和 学生表
分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择一对一
相对使用比较少。
例如:人和身份证、员工表和简历表
分析:一个人只有一个身份证,一个身份证只能对应一个人
2.1 一对多(1:n)
一对多建表原则
在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
2.2 多对多(m:n)
多对多关系建表原则
需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键
例如:
一个用户收藏多个线路,一个线路被多个用户收藏
-- 用户表
create table tab_user (
uid int primary key auto_increment,
username varchar(100) unique not null,
password varchar(30) not null,
name varchar(100),
birthday date,
sex char(1) default '男',
telephone varchar(11),
email varchar(100)
)
-- 路线表
create table tab_route(
rid int primary key auto)increament,
name varchar(100),
price double
)
-- 中间表
create table tab_favorite(
rid int ,
date datetime,
uid int,
-- 创建复合主键
primary key(rid,uid),
foreign key(rid) references tab_route(rid),
foreign key(uid) references tab_user(uid)
)
2.3 一对一(1:1)
在实际的开发中应用不多。因为一对一可以创建成一张表。
一对一关系建表原则
可以在任意一方添加唯一外键指向另一方的主键
三、 数据库设计的范式
3.1 范式的概念
设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求。
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
3.2 三大范式
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
满足最低要求的范式是第一范式(1NF)。
在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。
一般说来,数据库只需满足第三范式(3NF)就行了
3.3 第一范式(1NF)
数据库表的每一列都是不可分割的原子数据项,不能是集合、数组等非原子数据项。即表中的某个列有多个值时,必须拆分为不同的列。
简而言之,第一范式每一列不可再拆分,称为原子性。
3.4 第二范式(2NF)
在满足第一范式的前提下,表中的每一个字段都完全依赖于主键。
所谓完全依赖是指不能存在仅依赖主键一部分的列。
简而言之,第二范式就是在第一范式的基础上所有列完全依赖于主键列。
当存在一个复合主键包含多个主键列的时候,才会发生不符合第二范式的情况。
比如有一个主键有两个列,不能存在这样的属性,它只依赖于其中一个列,这就是不符合第二范式。
第二范式的特点:
- 一张表只描述一件事情
- 表中的每一列都完全依赖于主键
3.5 第三范式(3NF)
在满足第二范式的前提下,表中的每一列都直接依赖于主键,而不是通过其它的列来间接依赖于主键
简而言之,第三范式就是所有列不依赖于其它非主键列,也就是在满足 2NF 的基础上,任何非主列不得传递依赖于主键。
所谓传递依赖,指的是如果存在"A → B → C"的决定关系,则 C 传递依赖于 A。
因此,满足第三范式的数据库表应该不存在如下依赖关系:
主键列 → 非主键列 x → 非主键列 y
3.6 三大范式小结
1NF
原子性:表中每列不可再拆分。2NF
不产生局部依赖,一张表只描述一件事3NF
不产生传递依赖,表中每一列都直接依赖于主键。而不是通过其它列间接依赖于主键。
四、总结
- 数据库中表字段的约束:
- 主键约束:primary key
- 非空约束:not null
- 唯一约束:unique
- 外键约束:foreign key
- 表和表直接的三种关系
- 一对一
- 一对多 :在多的一方建立外键,指向一的一方的主键
- 多对多 :要借助第三张中间表,中间表中的两个字段作为外键,分别指向两张表的主键
- 数据库的三大范式
- 第一范式(1NF):每一列都是不可分割的原子数据项
- 第二范式(2NF):在1NF基础上,不产生局部依赖,一张表只描述一件事情
- 第三范式(3NF):在2NF基础上,不产生传递依赖,表中每一列都直接依赖于主键
下篇文章将会介绍多MySql中多表查询的相关知识。
注:由于本人水平有限,所以难免会有理解偏差或者使用不正确的问题。如果小伙伴们有更好的理解或者发现有什么问题,欢迎留言批评指正~