1. 第一范式(每列原子性)
第一范式要求所有的域都是原子性的,即每一列都不可(不须)分割。
以学生表为例,学生表有姓名、学号、年龄、性别、家庭住址等信息组成。在这个表中,可以看作所有列都不可分割(假设地址中的省、市、区、详细地址在本应用中是组合在一起的,不会拆分开来用。从这一点来看,地址列不可/不须分割),所以是满足第一范式的。
第一范式的合理性也需要结合实际需求来,上表满足第一范式是有一个前提条件,就是地址中的省、市、区、详细地址在本应用中是组合在一起的,不会拆分开来用。 假设本应用中需要把省、市、区、详细地址拆分开来使用,比如统计某省、某市、某区有多少学生,从而安排合适的校车接送。那上述设计就不满足数据库的第一范式了。此时就需要把地址拆分开来,才满足第一范式。
每列是否满足原子性是根据当前应用来判断的,并不是绝对的,就像本例中的地址一样。甚至是姓名在不同的应用中也可以说它满足满足或不满足原子性(假设需要把姓和名拆开…),所以在实际项目中一定要灵活处理。
2. 第二范式(要有主键,且实体属性完全依赖主键)
第二范式首先要求数据表必须要有主键,可以是单列构成的主键也可以是多列组合构成的主键。满足第二范式的表一定要先满足第一范式。
为什么要有主键?
因为要确保这一行数据的唯一性,因为主键本身的唯一性,就保证了这一行数据的唯一性,这样才能定位到这行数据。就像学生信息表,学号便可以当作主键来用,因为学号一定唯一。而姓名不可,因为可能会有重名,重复了就没有唯一性了。
实体属性完全依赖主键是什么意思?
是指每一列都和主键相关,并且不能只与主键的某一部分相关(主要针对联合主键)。
2.1 非联合主键情况
就像上面的学生信息表,主键number = 2020010223就已经决定了当前这一列归学号为2020010223的小明同学所有。这一列只能存放小明的年龄、性别、家庭住址等信息,而不能把小红的年龄、性别、家庭住址存放到这一列。如果把小红的年龄、性别、家庭住址存放到这一列,那这些属性就和主键没有任何关系了。
接下来再举个稍微复杂点的例子。
这张表里的班级名、语文老师名、英语老师名依赖小明吗?
不依赖!!!即使没有小明这个学生,也依然有高二三班,一个叫李明的语文老师和一个叫托尼的英语老师。所以说上述设计不满足数据库设计的第二范式。可以按照以下方式将上表更改成满足第二范式的 :
将班级信息单独抽取出来放到一张表中,在原来的学生信息表中新添加班级id列,作为外键。
学生信息表:
班级表:
这样一来就满足数据库设计第二范式了。
接下来我们再看点更复杂的。
2.2 联合主键情况
在前面我们还提到了一点:不能只与主键的某一部分相关(主要针对联合主键),这是怎么回事呢?一起来看一下吧!
假设有一张订单表是这样的:
这张表的主键是由order_id和book_id联合组成的。
mysql> show create table orders;
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| orders | CREATE TABLE `orders` (
`order_id` int(11) NOT NULL,
`book_id` int(11) NOT NULL,
`book_name` varchar(128)