数据库设计基本原则
数据库设计范式
1.第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
比如用户的地址,系统设计时可以只用一个字段表示例如:深圳市南山区国人通信A座XXX号。但系统会经常访问地址的城市,例如在快递单上,填写快递单时会有发出的城市这样方便快递流转,这样快递查找这些也是很方便的。那样就有必要将地址查分以下:省、市、区、详细地址。我们在一些购物网站填写收货地址也是一样。
2.第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
这个还举个购物的例子。比如用户下单会生成一个订单。订单表可能会包括:订单ID,商品ID,用户ID,数量,收货地址ID,单价,快递单号等。一个订单下会有多个商品,是一对多的关系,订单ID和商品ID属于联合主键,但收货地址,快递单号与订单ID是一对一的关系. 所以应该将上面的分出两个表:一个订单发货表,一个订单明细表。发货表主要是包括 订单ID,收货地址ID,快递单号等这些信息,而明细表主要包括订单ID,商品ID,用户ID数量,单价等信息。
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
经常遇到字段Type类型,比如商品类型:日用品、家电等类别。在商品表中直接将商品类型加到属性里:商品ID,商品名称,商品类型ID,商品类型名称等。这样的设计我也有见过可能觉得是为了省事,其实这样一点都不省事,会出现冗余。理想的设计是将商品类型另分出一个表:商品类型ID,商品类型名称。
数据库设计原则
去冗余:
避免冗余属性,冗余属性会带来数据不一致性;
学生选课系统中,老师可以开课、学生可以选课,数据库设计中,课程可以由课程编号和课程名称等确定;
如果现在维护两个表,一个表A存储课程信息(课程编号、名称、简介、学分、院系等),另一个表B存储开课信息(有哪些课程开课),如果B中重复存储了A的课程名称、简介、学分、院系等信息,一旦A中的信息更新,B中和A中信息便出现不一致;
正确的做法是,B中只存储课程编号,并以此和A相关联;
解耦合:
一个表只存储它应该存储的信息,和此表无关的信息放到另一个表去存储,表之间尽量解耦;
上面的例子中,A中存储且只存储面向课程的信息,另外有表C,存储且只存储面向学生的信息(学号、姓名、性别、年龄、选课id等),对于“课程级别”的信息,应当坚决的存储在A而不是C中,而且尽量避免将A、C合并成一个表(可能刚开始是设计成一个表),而且A、C间尽量解耦;
字段不可再分:
一个字段中不要出现分隔符,或者在一个字段中存储多个信息;
例如,first name和last name不要放在同一个字段中
考虑性能:
上述原则可能造成多表连接查询的情况出现,降低性能;
如果性能成为主要矛盾,则上述原则也不绝对;
数据库命名原则
数据库的命名会直接影响到上层应用的名称,所以要和业务部门仔细讨论、慎重确定;
每个属性名在数据库中只有唯一的含义,number这个属性名可能表示电话号码或是房间号,这是一种容易引起歧义的命名;
数据库的名词要一致,不能在这个地方叫一个名字,到另外一个表又叫另外一个名字;
boolean类型的命名要用
is_xxx
格式;
数据库设计其他注意事项
一个字段不要有多个用途,空间不是问题,清晰才是重点;
数据库性能提升方案
使用索引会大大提升查询效率,同时降低在被索引的表上INSERT和DELETE效率;
分离频繁和不频繁使用的数据到多个表中;
例如,原先,一个表中保存用户名、密码、年龄、个人简介、学校等信息,但是发现访问用户名、密码、年龄的频率远高于其他字段,此时就应当将这个表分为两个表,分别存储频繁访问项和非频繁访问项;