昨天有人问我数据库的设计原则,一年多没做服务端这块也基本忘干净了,就记得什么二级、三级什么的(别误会这不是黄片看多的结果),大学的时候也学过数据库,大学时也从需求到数据库设计再到实现独立完成了一个项目,对这数据库这块我还是有把握的,像什么存储过程触发器事务锁等,这些理论的知识也忘差不多了,可能藏在脑中的深处。今天网上查了下,原来三级是范式(学霸的我还是可以从脑海中想起的)。下面就回顾一下3级范式。
1.第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
比如用户的地址,系统设计时可以只用一个字段表示例如:深圳市南山区国人通信A座XXX号。但系统会经常访问地址的城市,例如在快递单上,填写快递单时会有发出的城市这样方便快递流转,这样快递查找这些也是很方便的。那样就有必要将地址查分以下:省、市、区、详细地址。我们在一些购物网站填写收货地址也是一样。
2.第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
这个还举个购物的例子。比如用户下单会生成一个订单。订单表可能会包括:订单ID,商品ID,用户ID,数量,收货地址ID,单价,快递单号等。一个订单下会有多个商品,是一对多的关系,订单ID和商品ID属于联合主键,但收货地址,快递单号与订单ID是一对一的关系. 所以应该将上面的分出两个表:一个订单发货表,一个订单明细表。发货表主要是包括 订单ID,收货地址ID,快递单号等这些信息,而明细表主要包括订单ID,商品ID,用户ID数量,单价等信息。
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
经常遇到字段Type类型,比如商品类型:日用品、家电等类别。在商品表中直接将商品类型加到属性里:商品ID,商品名称,商品类型ID,商品类型名称等。这样的设计我也有见过可能觉得是为了省事,其实这样一点都不省事,会出现冗余。理想的设计是将商品类型另分出一个表:商品类型ID,商品类型名称。
4.简单理解三级范式
第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。 没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理 数据模型设计时考虑。降低范式就是增加字段,允许冗余
5.数据库设计注意的几点
1.注意原始单据与实体间的关系以及实体与实体间的关系
原始单据与实体间的关系:例如一个订单,可能会有订单发货信息表、订单商品明细表。一个单体用两个实体组成。
实体与实体的关系:和上面原始数据与实体间的关系一样,都是有一对多、一对一、多对多的关系,一对多联合主键,多对多的话分成一对多,用两个表实现。
2.主键
主键分业务主键和逻辑主键。有时候正确设置主键可能减少数据库冗余。还是用上面订单举例。我们生成订单时可以用商品ID,用户ID设置加上时间算上联合主键。但这样每个关于订单的表总不能都要加上上面的几个字段才能获得吧,这样会更麻烦。订单ID算是逻辑主键(自增类型、uuid或guid)也可算是业务主键(比如ID是用一定规则拼接的有一定业务规则的),有了它找订单就会更方便。
3.约束
约束主要是为了防止数据出错。
域的完整性:年龄是要在一定范围的等。
参照完整性:用PK、FK、表级触发器来实现。数据要有一个参照物,在参照物内的才是正确的数据。
用户定义完整性:它是一些业务规则,用存储过程和触发器来实现。比如插入数据时有时候数据要符合一定的规则。
6.总结
说到最后其实这些都是理论知识,最重要的还是要自己实现自己体会感悟总结。我这也是属于瞎逼逼,毕竟自己独立完成的项目很少也就一两个,欢迎大家来吐槽交流。