《数据库设计》
对于一个系统,数据库的设计是非常重要的,数据库设计决定了以后数据好不好维护。后期需求好不好展。同时也决定了系统的性能。一个坏的数据库设计一个功能点的改动可能会设计多张表的改动。一不小心可能就会引起数据的不一致。为了解决这些问题。在数据库设计之初就要考虑这些问题。减少后期系统维护量。说了这么多数据库设计的重要性那么数据库设计应该考虑哪些问题呢?
一、范式与反范式的设计
范式设计的目的是为了减少数据冗余从而节约存储空间提高查询效率,同时也使得数据一致性容易得到维护。例如一个简单的例子:一个选课系统设计如下。建立学生信息表与课程信息表。当学生进行选课操作时。建立选课表使得学生与课程建立关系。建立关系只需要建立主键ID的关系。
学生表:
ID
姓名
编号
课程表
ID
课程名
课程描述
选课表
学生ID
课程ID
课程描述 课程ID
上面这种设计是标准的按照范式设计的表格。如果我们要看小明选了哪些课程只需要将这3张表做个关联查询就行了。反范式的设计主要考录历史数据要反应历史问题。需要将数据冗余到表中。同样用一个简单的电商系统来说明。
商品表:
ID
商品名称
单价
库存
用户表
ID
姓名
年龄
地址表
用户ID
地址
练习电话
订单表
ID
订单编号
用户ID
用户名
地址
金额
订单商品表
订单ID
商品名称
商品单价
商品数量
这种设计的考虑就是反应历史情况按照历史处理。比如说小红下了一个2000元的苹果手机一代。订单已经生成并且支付。这个时候店家为了促销将苹果一代手机价格降低到1800。如果数据不冗余到订单表。快递发货时打印出来的订单价格与用户实际支付的价格就会有出入,给用户造成误会。
一个反范式设计出现的问题。曾经接手过一个系统其中的问题。就是采用反范式设计出现的问题。
举上面两个典型例子的目的时为了提醒我们设计数据库时一定要考虑范式和反范式设计。具体采用什么方式就要分析我们的业务是属于哪种情况视具体情况而定采用哪种方式。这种情况更多用到涉及到财务方面。涉及到以后财务对账。所以数据冗余相当重要。
二、扩展性设计
项目初期业务场景数据模型是一对一,并且分析后期有可能会变成一对多。这种情况不要为了前期方便设计成一对一数据模型。这样做到后期可能得不尝失。这就是数据拓展性设计需要考虑。比如如下两种设计
第一种
用户表
姓名 varchar
年龄 varchar
昵称 varchar
省 varchar
市 varchar
区 varchar
街道 varchar
第二种
用户表 地址表
id int ---------> 用户ID int
姓名 varchar 省 varchar
年龄 varcher 市 varchar
昵称 varchar 区 varchar
街道 varchar
明显第二种好于第一种。并且得益于关系型数据库的成熟基于主键表关联查询的效率很高。不用担心因标间关联查询的性能问题。在很多业务场景下都不用查询用户地址信息。如果只需要查询或者统计用户的一些基础信息。地址信息会使得该表的高水位线被顶到很高的水平影响全表扫描的效率。同时很多用户没有录入地址信息。导致该表有很多空值数据。将表拆分后能够提高其他业务场景查询效率是一个很好设计思路。
三、数据库约束
数据约束最好是在数据设计之初就定义好。包括非空约束数据唯一性约束。这样可以解决很多系统空异常,并且使得数据更好维护。如果不这个做,当系统运行一时间后。某些数据不该为空的变成了空再来补数据你就会明白我的良苦用心了。并且有现成的东西给你加一道防线何乐而不为。
四、数据库访问权限界定
数据库访问权限一定要控制在自己的系统范围内,严禁其他系统直接操作数据库。系统需要与其他系统进行信息交换,或者数据变更,应该采用本系统开发接口给外部系统进行调用并且对接口调用进行日志记录,而不是直接开放数据库给对方。这么做主要是方便核查异常数据写入场景分析问题源。快速定位问题源。同时通过分析接口调用日志分析外部系统问题。
五、表字段最好考虑添加创建时间和修改时间
这个设计主要是考虑到平时数据维护和数据分析用,不一定时业务上使用。如果某段时间业务出问题,可以通过数据的创建时间和修改时间来找到这部分异常数据。是人就会犯错,我们尽量做到犯错可挽回,当我们临时需要手动处理一些数据。一不小心把数据有弄错了,通过这两个字段还可以找到并重新处理这两个数据同时做数据复原。
代码删除了可以重新写一份。数据库删除了就什么都完了。所以数据是系统的灵魂。维护数据的正确完整至关重要。而做好上面这些事项。可以使得在日常的工作中更加轻松。
总结:
{ 收集信息
设计数据库的步骤 { 收识实体
{ 收识每个实体的属性
{ 标识实体间的关系
概要、详细设计阶段设计数据库的步骤
数据库设计 绘制E-R图
将E-R图转换为实体关系模型
利用三大范式规范化表设计
{ 第一范式确保每列的原子性
三大范式内容 { 第二范式要求每个表只描述一件事情
{第三范式要求表中各列必须和主键直接相关,不能间接相关