第一范式:原子性
数据库的每一列不可以再分,如,“地址”这一列还可以分为“省”、“市”、“街道”,如果必须自己填写完整的地址当然是不需要再分,但是如果需要先选出来由系统拼接的话,地址这一列必须要分成“省”、“市”、“街道”,一个省对应多个市,一个市对应多个街道,这种一对多的关系,3张表来存储所有的地址,假如有n个省,每个省有m个市,每个市有j个街道。每个“省”、“市”、“街道”用2个字符表示(假设一种理想的情况),那么所有的地址n*m*j条,使用[m+(m*n)+m*n*j]*2个字符。另一种情况地址不划分为3个表,省市街道的数据全写在一个列内,那么需要3*2个字符,表示地址n*m*j条需要n*m*j*6个字符,这还是仅仅每个人地址不同并且人数和地址数相同的情况,如果多个人对应同一个地址(这里只算到街道),那么这张表将会有更多冗余。
第二范式:属性完全依赖于主键,每一行的数据只能与一列相关,每行记录只能做一件事,也就是一张表只能描述一类对象.
比如一张酒店订单表 包括 订单号 房间号 联系人 联系人电话 身份证号,而一个人可以产生多张订单订多个房间,那么在这张表中,就要把 联系人 联系人电话 身份证号这些信息重复写n(订单数)遍。如果把个人信息分出来单独存到一张表中,就不需要将身份信息随着订单的增加写多次,把相乘的数据条数变成了相加的数据条数
第三范式:每一列只能与主键直接相关不允许间接相关。
数据不能存在传递关系,即每个属性都跟主键有直接关系而不是间接关系。像:a-->b-->c 属性之间含有这样的关系,是不符合第三范式的。
比如Student表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)
这样一个表结构,就存在上述关系。 学号--> 所在院校 --> (院校地址,院校电话)
这样的表结构,我们应该拆开来,如下。
(学号,姓名,年龄,性别,所在院校)--(所在院校,院校地址,院校电话)
同理把相乘的数据条数变成了相加的数据条数,减少了冗余
当然第三范式为了需求可以不严格遵守的,这里不再多说。以上是我对数据库三大范式与表之间的对应关系的个人思考,遵守三大范式有助于大大减少冗余,不足之处及错误之处请在评论里指出。
————————————————
文章部分内容参考「凉_ting」的文章
参考链接:https://blog.csdn.net/qq_40899182/article/details/81706253