数据表设计三范式
第一范式:列唯一,列字段不可分
不可分就是说所有的字段都是最小单位,不可进一步拆分。例如用户表中的身份证号、邮箱地址以及手机号码都不能再拆分。如果是姓名,国外可以进一步分为First Name(名)和Last Name(姓),外国人的姓名不能作为一个字段,中国人的名字不会进一步拆分,因此可以把姓名作为一个字段。
第二范式:行唯一,有主键,要求非主键字段完全依赖于主键
数据表里的每一条数据记录都是可唯一标识的,而且所有字段都必须完全依赖主键。如果没一行都没有主键,就没有唯一性,没有唯一性在集合中就定位不到这行记录,因此每一行要有主键。
为什么要完全依赖主键呢?因为如果不依赖主键,就找不到它们。只要依赖主键,他们就是唯一的,只要是唯一的,就可以通过主键找到相关的信息。其他字段必须要和他们的主键相关,因为不相关的东西不应该放在一行的记录里面。
第三范式:消除传递依赖,通过关联字段消除冗余
比如有一张用户表,和一张项目表一对一关联,每个用户负责对应的一个项目。在用户表中创建管理字段pid,用来存储项目id,但是项目名称字段p_name是没有必要创建的,因为它属于冗余字段,会浪费存储空间,所以应该被消除。项目名称p-name应该完全依赖项目id这个主键,可是项目名称p_name现在是在用户表里,用户表的主键可是用户id,因此应该消除传递依赖,将p-name字段删除。
在用户表里添加项目名称字段p-name还有一个问题,就是容易导致数据不一致。比如我们将项目名称修改后,但是用户表的项目字段没有及时更新,就是导致数据不一致。
但是规定是规定,不一定要死脑筋养个遵守,有时候我们就是需要添加一个冗余字段来提升查询效率。
数据库设计四部曲
(1)需求分析
慎始才能善终,在设计之初一定要充分了解客户的需求,清楚客户需要什么样的功能,了解系统用户量和数据量有多大。如果没有充分了解需求,草草进入下一设计阶段,那么后期可能会出现返工,这样只会浪费更多的人力成本,严重打击员工积极性。
客户的需求分析从对话开始,记录形成需求文档,并组织需求评审会,把需求文档和原型设计整理出来,然后进入设计环节。
(2)设计
充分了解需求文档和原型设计后,就可以开始设计数据库。我们需要根据需求分析里面包含的各种模型来理清模型之间的关联关系,根据模型来设计库表、字段、索引。如果数据量特别大,可能还需要分库分表设计,设计过程中要考虑表的扩展性问题,同时遵守设计三范式。设计阶段也是非常重要的,好的设计可以让团队少加班,提高开发效率。
2.1 具体操作为:阅读需求文档,结合E-R实体关联模型,提取出项的实体(名词);有了实体后,分析实体之间的关联关系,这样就可以构建出实体关系图,最后再确认实体拥有的属性。
2.2 E-R实体模型梳理完成后,就要开始设计数据库和表。每个实体被设计成一张表,若是多对多的关联关系,则需要设计关联表,若是一对多的关系,只需要在多的一方设置关联字段即可。
2.3 数据库和数据表的命名原则如下:
(1)库名和应用名称尽量一致,比如开发教务管理系统,应用名称是edu-manage-system,数据库的名称就可以取该名称;
(2)除非有特殊要求,数据库名字统一使用小写字母,数字及中画线 (注意不是下画线);
(3)一定要设置数据库的编码,例如utf8、utf8mb4等;
(4)表名 不适用复数名词,例如students、teachers等;
(5)表的命名建议遵循'业务名称缩写-表的作用',一个庞大的系统,表可能有上百张,不同的表存储不同的业务数据,
(6)字段名建议使用小写字母,数字,下画线,禁止以数字开头,禁止两个下画线中间只出现数字;
(7)字段名称需要慎重考虑,因为数据库字段名的修改代价很大,修改字段名称,对应的程序代码也要进行调整,还有可能会导致表被锁;
(8)主键名称一般叫作id,主键类型通常有int、bigint、varchar等。主键字段不要使用业务字段,如身份证号码,手机号码等。
(9)设计关联表时,表后缀名称为"XXX_rel"
(3)实现
根据设计结果,落地实施,有了详细的设计图纸和数据结构表,实施起来就会轻松很多。
(4)后期优化
项目上线后必然会出现各种问题,如性能问题或异常问题,因此后期优化和迭代不可避免。
本文内容大多来自黄文毅 著的 《像程序员一样使用MySQL》的读书笔记
