数据库设计注意事项和原则

引言数据库设计是信息系统设计的基础,一个好的数据库设计在满足了软件需求之外,还要易维护、易扩充等等要求。当然,对专家们反复强调的数据的一致性、冗余性、访问效率等问题的解决,很大程度上取决于数据库设计者的经验和专业水平。但这不妨碍我们根据过去的经验,从实用的角度给出数据库设计所要要考虑的问题并尽可能给出相应的解决方案,从而给信息系统的数据库设计者一些有益的启示。(注:这里的数据库设计主要指数据库中表和视图的schema设计,不涉足数据库系统中其他方面的设计)那么怎样才算是一个好的数据库设计呢?以下给出一个一般性的标准。

一、一个好的数据库设计首先要满足用户的需求

所有信息系统最后都将提交给最终用户使用,对于这一点,相信大家都已经达成共识。但是准确地把握用户的需求是很难的,虽然各方面的专家已经从不同方面给出了解决方案,但是用户需求仍然是软件工程中最不确定的因素之一。

二、一个好的数据库设计要便于维护和扩充

为了应对用户需求的修改和添加,也为了满足各种不同的软硬件环境下系统的使用,大部分信息系统都不得不在其生命期中进行升级和调整。在这些升级、调整中,又有相当部分会涉及到数据库设计的修改,因此,数据库设计最好从一开始就能在易维护、可扩充的角度多加斟酌。

1、不要为各种编号字段的设定固定的意义
而是最好通过对照表来建立这种编号和意义的对照关系。举例来说,很多设计者习惯给部门信息给出固定的编号,这种设计有个致命的缺陷:那就是由于这种对照关系既然不体现在数据库中,就必然要用业务逻辑来进行解释,这样一来,一有新的调整就不得不更新业务逻辑代码,也就非常容易不一致的错误。

2、枚举信息要体现在相应在对照表中
而不是体现在使用该信息的表中的值字段,这样做的好处是当用户希望用该枚举信息作为查询条件的时候,通过参照表的方式可以很容易的建立这些信息,另外也避免了当多个表格中都含有该枚举信息有可能引起的不一致。

3、用关联表建立表和表之间的多对多关系
而不要用一个字段解析的方式进行,举例来说,为了描述用户(UserInfo)和角色(RoleInfo)之间的关联关系,我们要建立对照表UserInfo_RoleInfo,而不要试图在用户表中建立一个较长的字段,如Roles(用RoleID1;RoleID2…的形式构成)来代替,因为这样一来字段解释需要在业务代码相应的解析代码,二来由于Roles定长,无法满足用户角色的扩充。

三、一个好的数据库设计要具有“可读性”

如同编程书籍中反复强调的程序员一定要在代码的可读性方面下功夫一样,考虑到信息系统将来的升级和维护可能要要由另外一批人来进行,因此数据库设计必然也要具有可理解性。对此,我们参照提高代码可读性的常用方法,给出一些建议:

1、用设计文档来提高数据库设计的可读性
这点基本对应于“可读性”代码里面的注释。在一个合格的数据库设计文档中必须给出数据库中的每个表、每个字段、表间的关联关系以及各种约束的意义以及由来,从而有可能让开发者根据用户需求和设计文档就能理解正确数据库的设计。

2、给表和视图起一个有意义的名字
这点对应于coding规范中的变量和函数的命名,很显然,CustomerInfo的名字很容易联想到该表中含有客户信息,而把它命名为Table0001只能让人感到费解外。另外,如果DBMS提供表和视图名的大小写支持,该名称最好由每个构成单词(首字母大写)拼接而成。

3、用前缀给出表和视图内容之外的其他信息
如给参照表Ref_前缀,这样就可以让业务逻辑实现人员根据表的名字知道他所要操作的是不是张参照表,从而帮助他更快地理解详细设计,并有可能及早发现里面的错误。同样,给所有视图加上V_前缀,就可以让业务逻辑编程者很容易地知道他现在面临的是一个表还是视图,从而避免了对视图进行更新操作这种低级的错误。

4、给每一个字段起一个有意义的名字
如给CustomerInfo表中的电子邮件字段起名EMail让人很容易明白它的准确含义,而Field05则让人不知所云。基于同样的道理,数据库设计中也不能给字段起一个张冠李戴的名字。

5、字段命名要考虑上下文
举例来说,在UserInfo表中,用UserName来表示用户名字段就不如Name来的更加合适。这种情况画蛇添足的情况在对照表的设计中体现得尤为明显,如把部门对照表(Ref_Department)中的部门ID字段命名为DepartmentID,把部门名称字段命名为DepartmentName等等。

6、视图的设计不要牵扯到其他视图
与代码设计中函数调用最好不要嵌套过多层次相对应,为了便于数据库设计的阅读人能够很好地理解设计,视图最好直接建立在表上。

7、同一表中的记录最好不要相互引用
这种引用关系不仅让数据库设计的阅读人云里雾里,也不便于业务逻辑代码的编写。

8、关联表的命名用关联的表名中间加下划线连接构成
如学生(StudentInfo)和课程(CourseInfo)的关联表起名StudentInfo_CourseInfo。

四、一个好的数据库设计能够满足空间和效率的要求

对于一个信息系统来说,在实现用户需求的基础之上,保证一个较低的空间占用以及短的响应时间都是理智的客户所愿意看到的。那么在这一方面,数据库设计又要做些什么工作呢?

1、使用varchar而不要使用char字段
对于不定长信息如用户的简介信息,varchar的使用可以减少近一半的空间占用。当然这点不能一概而论,如用相应长度的char存储定长文本数据就比varchar来的合适。

2、不要使用BLOB字段存放“大数据”
BLOB字段诚如其名,本身是为存储二进制大数据而出现的,同样的道理也适用于某些DBMS所引入的TEXT字段。因为对于一般信息系统而言,最长的字段往往是一些描述文本信息,而DBMS对char/varchar的长度基本能满足这种需求。因此积极建议设计者对一些貌似很长的文本的最大允许长度进行确认,在此基础上参照DBMS中的开发手册来决定是否采用大字段。

3、不要使用设计器缺省的字段长度
这种做法一方面纵容了设计者对用户需求的一知半解以及对设计敷衍了事的不良习惯,另外一方面也在数据的存储上浪费了不少的空间,因为使用缺省字段长度的情况往往发生在字段上。

4、不要轻易使用unicode文本字段
DBMS对unicode的支持在帮助产品国际化的同时,也在一定程度上带来空间上的浪费,尤其是在当要存储的文本中的基本都是ASCII字符的情况下,这种浪费尤为明显。因此,建议设计者在选择unicode的理由,一定是出于国际化的考虑,而不是其他。因为大多数的大字符集和ASCII字符并存情况下所要碰到的问题基本上都已经由DBMS提供商解决。

5、使用预计算表来提高响应速度
跟数据仓库里面的某些思路相似,当业务逻辑中需要用倒根据历史信息得来的统计数据时,最好由独立于系统的预计算模块或相应的DW工具定期完成这些统计数据的预计算。

五、一个好的数据库设计可以简化业务逻辑的设计

所有的数据库设计都不是孤立的,它通过相应的业务逻辑实现(三层结构中还有表现层)来形成最终的产品,因此一个好的数据库设计应该能够帮助降低业务逻辑的编写难度,最起码不要给业务逻辑的设计、编码带来额外工作。

1、所有允许为空的字段必须是基于用户需求,而不是出于设计上方便的考虑。这样带来的好处是让详细设计中的某些错误和疏漏(如在设计中没有考虑对非空字段的内容检查)在编码和单元测试阶段就被发现,从而避免了进一步扩散,有助于提高软件的质量。

2、不要业务逻辑代码实现唯一性约束
对数据库表中的某些字段(或者多个字段的组合)的唯一性约束应该尽可能地加到数据库端。因为这种约束工作交给业务逻辑中去实现代价高昂而且不可靠。

3、关联约束一定要建立在数据库端
分析出设计中所涉及的主外键引用关系并体现在数据库设计中。这一条出于两点考虑:降低业务逻辑的编写难度和数据关联性约束的要求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AtCoder】ARC078

C - Splitting Pile 枚举从哪里开始分的即可 #include <bits/stdc.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar( ) #define enter putchar(\n) #define MAXN 200005 #defi…

20172325 2018-2019-1 《Java程序设计》第二周学习总结

20172325 2018-2019-1 《Java程序设计》第二周学习总结 教材学习内容总结 3.1集合 集合是一种聚集、组织了其他对象的对象。集合可以分为两大类&#xff1a;线性集合和非线性集合。线性集合&#xff1a;一种其元素按照直线方式组织的集合。非线性集合&#xff1a;一种其元素按某…

数据库视图

测试表:user有id&#xff0c;name&#xff0c;age&#xff0c;sex字段 测试表:goods有id&#xff0c;name&#xff0c;price字段 测试表:ug有id&#xff0c;userid&#xff0c;goodsid字段 视图的作用实在是太强大了&#xff0c;以下是我体验过的好处&#xff1a; 作用一&…

题解 luogu P2568 GCD

题解 luogu P2568 GCD 时间&#xff1a;2019.3.11 欧拉函数前缀和 题目描述 给定整数\(N\)&#xff0c;求\(1\le x,y \le N\)且\(\gcd(x,y)\)为素数的数对\((x,y)\)有多少对. 分析 枚举素数\(p\), 先求出\(1\le x,y \le \left \lfloor \dfrac n p \right \rfloor\)且\(\gcd(x, …

解决前后台发送请求或者接口之间发送请求乱码的问题

前后台传中文乱码&#xff1a; 前台使用encodeURI 进行编码 后台使用decode进行解码 如果接口之间调用出现乱码.接收方是&#xff1f;&#xff1f;&#xff1f;&#xff1f;这种。传送方式明文的处理方式&#xff1a; 发送方使用decode 进行编码&#xff1a; 接收方使用的ecod…

MSDN帮助文档 无法显示该网页 的问题解决方案(转)

MSDN帮助文档 "无法显示该网页" 的问题解决方案 以前就遇到过这样的问题&#xff0c;还以为是IE7导致的。后来重新安装了IE7也没有解决。后来就重新安装MSDN了&#xff0c;非常郁闷。今天终于知道原因了。因为开了HijackThis删除了一些注册协议&#xff0c;然后发现M…

.net Core发布至IIS完全手册带各种踩坑

服务器环境配置 和各位大爷报告一下我的服务器环境 : Windows Server 2012 iis 8 小插曲开始: 运维大哥在昨天给了我一台新的server 0环境开始搭建 。 并且没有安装任何的系统补丁。 第一件事情请开始打 补丁 打完补丁之后有时补丁会不完全 ,所以需要去官网获取补丁: KB2919355…

Unity --- MeshRenderer之网格合并

创建如图所示的对象结构,parent为空对象&#xff0c;然后将下面的代码挂载到parent对象上运行即可。 1 using UnityEngine;2 using System.Collections;3 4 public class CombineMeshAndMaterials : MonoBehaviour5 {6 void Start()7 {8 CombineMesh();9 }…

css 盒模型的属性

1、盒模型 2、display 3、浮动转载于:https://www.cnblogs.com/Tang854416/p/9676424.html

前后端分离

、前后端分离的好处 &#xff08;1&#xff09;彻底解放前端 &#xff08;2&#xff09;提高工作效率&#xff0c;分工更加明确。 &#xff08;3&#xff09;局部性能提升 &#xff08;4&#xff09;降低维护成本 2、前后端分离的概念 后台只需要提供API接口&#xff0c;…

Win10还原被Windows Defender隔离的文件

Win10最新版本的Windows Defender隔离/删除的文件没有还原的选项&#xff0c;导致很多破解文件或是注册机直接隔离&#xff0c;到威胁历史记录中去却无法恢复。经过各个尝试&#xff0c;到微软官方论坛中也尝试了很多方法&#xff0c;后来发现竟然恢复啦。各位小伙伴可以试试这…

AtCoder Grand Contest 013 题解

A - Sorted Arrays 贪心&#xff0c;看看不下降和不上升最长能到哪&#xff0c;直接转移过去即可。 1 //waz2 #include <bits/stdc.h>3 4 using namespace std;5 6 #define mp make_pair7 #define pb push_back8 #define fi first9 #define se second 10 #define ALL(x…

servlet架构解析

https://www.jianshu.com/p/d433b5fb87e2

(Review cs231n) Backpropagation and Neural Network

损失由两部分组成&#xff1a; 数据损失正则化损失&#xff08;data loss regularization&#xff09; 想得到损失函数关于权值矩阵W的梯度表达式&#xff0c;然后进性优化操作&#xff08;损失相当于海拔&#xff0c;你在山上的位置相当于W&#xff0c;你进行移动&#xff0c…

springboot restful

https://www.jianshu.com/p/733d788ea94d

【计算机算法设计与分析】——排序

一.排序 二.插入排序 &#xff08;1&#xff09;算法描述 &#xff08;2&#xff09;性能分析 &#xff08;3&#xff09;寻求优化 三.归并排序 &#xff08;1&#xff09;算法思想 &#xff08;2&#xff09;性能分析 &#xff08;2&#xff09;示例 &#xff08;3&#xff09…

QT 随机数生成

下面总结了QT中随机生成的方法&#xff08;仅供学习参考&#xff09;&#xff0c;分为旧方法和新方法&#xff0c;一般来说&#xff0c;旧的方法已经被抛弃&#xff0c;在开发新的应用中推荐使用新方法。 C Code 123456789101112131415161718192021222324#include <QCoreApp…

获取/设置IFRAME内对象元素的几种JS方法

获取/设置IFRAME内对象元素的几种JS方法 iframe浏览器ie文档微软&#xff11;。IE专用(通过frames索引形象定位)&#xff1a; document.frames[i].document.getElementById(元素的ID); &#xff12;。IE专用(通过IFRAME名称形象定位)&#xff1a; document.frames[iframe的name…

高并发

https://blog.csdn.net/java_xth/article/details/81162088

多人游戏服务器

https://www.getmangos.eu/转载于:https://www.cnblogs.com/aibox222/p/9682697.html