程序员应该知道的数据库设计的两个误区

然而,在我所经历过的项目中,某些数据库的设计会存在一些问题,尤其普遍的就是下面将要描述的这两点,个人觉得是应该避免的误区,总结出来与大家讨论。

误区之一 备用字段

现象描述:

在数据表中,不仅设计了当前所需要的字段,而且还在其中留出几个字段作为备用。

比方说,我设计了一个人员表(Person),其中已经添加了各种必要的字段,包括姓名(Name)、性别(Sex)、出生年月日(birthday)等等。大功告成之后,我忽然想到,将来系统中应该还会有很多其它与人相关的内容吧,比方说毕业院校,比方说工作单位等等,尽管现在根本不需要填写,以后可能还是会用到的吧。拍脑袋一项,那就加入5个varchar2型的字段,分别叫做Text1、Text2……Text5,然后又想,应该还有一些日期型的字段需要备用,就又建立了三个date型的字段,分别起名叫做date1、date2、date3,……

原因分析:

大家应该已经看出问题了,在这个数据表中存在大量暂时无用的字段,我们可以称之为备用字段,它们的作用是什么呢?就是以防万一,防备可能的情况

这似乎可以叫做防患于未然,等到时候需要的时候,就不需要在表中增加新的字段了,而且这样做的话,一个表的数据应该会被存储在相邻的物理空间中,这对于性能也是有好处的。

另外的原因就是,在古老的数据库中,如果改变数据库的定义(包括增加字段、改变字段的类型、删除字段等等),那么其中所有的数据就会丢失,所以这项工作非常麻烦,我们需要先建立临时表,将数据备份出来,然后创建新表,将数据导入其中,最后再删除原来的表。

问题所在:

这样的做法对于项目会导致很多问题,而且原先想要解决的问题并不一定能够解决,不信的话,请往下看。

问题一:增加大量备用字段,必定会浪费很多空间,尽管其中可能都没有具体的数据,但是仅仅是空字段也会占据一定的空间的。

问题二:由于命名的特点,如果没有完善的文档管理流程,用不了多久(可能也就是两三年),就没有人能够说清楚到底哪个字段代表的是什么意义了。就算有文档管理,这些管理工作也会比较麻烦,而且在每次使用的时候都需要申请,还有可能会出现冲突的情况。

问题三:增加了这些备用字段就真的会够用吗?不一定,因为我们只是每个类型的字段留出几个备用,如果数量超过,或者要使用特殊的、不常用的类型的时候,还是需要增加新的字段。比方说在上述的Person表中,我们要存储照片,那么可能就要增加一个blob类型的photo字段,这在初期设计的时候可不一定会留出这样的备用字段。而且如果没有完善的管理,谁又能说清楚倒底哪个字段已经被使用,哪个字段还可以使用呢?到时候还不是要增加新的字段。

解决方案:

其实上面的这种设计方式就是一种“过度设计”,我们应该做的就是“按需设计”,在经过详细有效的分析之后,在数据表中只放置必要的字段,而不要留出大量的备用字段。

当需要增加相关的信息的时候,就要具体情况具体分析:

如果数量很少,而且信息的性质与原表密切相关,那么就可以直接在原表上增加字段,并将相关的数据更新进去。

如果数量较大,或者并非是原表对象至关重要的属性,那么就可以新增一个表,然后通过键值连接起来。

对于表的数据的存储位置所导致的性能问题,我们可以通过在特定时间对数据库的数据进行重组来解决,而这项工作对于长期运行的数据库来说,也是需要定期进行的。

误区之二 有意义的编码

现象描述:

使用有意义的编码作为一条记录的ID,甚至作为数据库的主键存在,例如,一个员工的编码设置为0203004,其中02代表员工所在分公司,03代表员工所在部门,004代表员工进入到该部门的序号。

原因分析:

ID的设置方式大概有以下几种,一种是纯粹的流水号,从1开始,每次加1,或者对其将以改进,将数字转换成为字符串的格式,比方说“0000001”;一种是无意义的随机编码,比方说GUID;还有一种就是有意义的编码,特定的位数会代表一定的意义。

我想之所以大家这么喜欢使用这种方式,主要是因为想要从编码中就能够得到一些信息,甚至有些程序中还有专门的对编码进行解析的模块。就像我们的身份证号码一样,看到身份证号就可以知道办身份证时的所在地、生日、性别等信息。

问题所在:

其实有意义的编码会导致很多问题,请看:

问题一:对编码资源的浪费。如果是纯粹的流水号,那么从1到10000就可以代表一万条记录,但是,如果使用有意义的编码,很可能1000条记录就会让五位的编码不够用。我就遇到过真正的情况,我们公司的投保单号码的第一位就是有意义的,代表的时该投保单所属的渠道,后面跟着很长的一串数字(9位)。理论上来说,这些编码永远都不会用完,但是,最开始的三个渠道使用的是1、4、7三个编码,但是一次新保险法的实行,导致原有的投保单作废,于是又启用了三个数字2、5、8,接下来公司改名,三个渠道又分别将投保单报废,重新启用新的开头数字,就这样,短短的几年间,所有的投保单号码全都被用完了,其实打印出来的投保单不过100万张。

问题二:不一定是唯一的,难以作为主键。想一下,我们的身份证号码就是这样的。原先15位的时候,后三位是序号,而男性会使用奇数,女性会使用偶数,这样就是说,一个地区同一天生日的人,男女都不能超过500人,否则就会导致号码的重复,尽管出现这种现象的概率比较低,但是还是客观存在的。

问题三:代表的意义不一定准确。比方说用带有意义的编码来为员工定义工号,其中可能会有部门、职务等等意义,但是如果员工在部门间发生了调动,或者职级发生了改变,是否需要改变他的编码呢?改变吧,那么所有的历史数据都要随之修改一次,工作量会非常大;不改变吧,那么代表的意义就不再准确,我们就无法从编码中得到该员工准确的信息。

解决方案:

所以,对于编码,非常不建议使用有意义的编码,要么使用纯粹的流水号,但这样可能需要定义一个范围比较大的类型,对于海量记录的数据,可能会不够用;那样的话就可以使用GUID,这样编码永远都不会重复,而且会有大量的编码资源可用。

从上面的两点我们可以看出,在数据库设计的过程中,有一些在非常多系统中都使用了,但是却带来了很多问题的方法,对于这种情况,我们就应该仔细思考,然后痛下决心,坚决抵制。

(0)

相关推荐

  • 程序员应该知道的数据库设计的两个误区

    然而,在我所经历过的项目中,某些数据库的设计会存在一些问题,尤其普遍的就是下面将要描述的这两点,个人觉得是应该避免的误区,总结出来与大家讨论. 误区之一 备用字段 现象描述: 在数据表中,不仅设计了当前所需要的字段,而且还在其中留出几个字段作为备用. 比方说,我设计了一个人员表(Person),其中已经添加了各种必要的字段,包括姓名(Name).性别(Sex).出生年月日(birthday)等等.大功告成之后,我忽然想到,将来系统中应该还会有很多其它与人相关的内容吧,比方说毕业院校,比方说工作单

  • 分享20个数据库设计的最佳实践

    数据库设计是整个程序的重点之一,为了支持相关程序运行,最佳的数据库设计往往不可能一蹴而就,只能反复探寻并逐步求精,这是一个复杂的过程,也是规划和结构化数据库中的数据对象以及这些数据对象之间关系的过程.下面给出了20个数据库设计最佳实践,当然,所谓最佳,还是要看它是否适合你的程序.一起来了解了解吧. 1.使用明确.统一的标明和列名,例如 School, SchoolCourse, CourceID. 2.数据表名使用单数而不是复数,例如 StudentCourse,而不是StudentCourse

  • 10个Java程序员熟悉的面向对象设计原则

    面向对象设计原则是OOPS编程的核心, 但我见过的大多数Java程序员热心于像Singleton (单例) . Decorator(装饰器).Observer(观察者) 等设计模式,而没有把足够多的注意力放在学习面向对象的分析和设计上面.学习面向对象编程像"抽象"."封装"."多态"."继承" 等基础知识是重要的,但同时为了创建简洁.模块化的设计,了解这些设计原则也同等重要.我经常看到不同经验水平的java程序员,他们有的不知

  • 程序员 代码是从头编还是使用框架好呢?

    在编码的世界里,程序员永远不要期待东西保持静止太久.技术已经决定了我们如何互动.创造.学习.生活等,并且不断发展.对于程序员来说,只有靠近和依赖最新技术才能完成任务.而且最深刻的改变之一就是框架.编程语言以及两者之间的范式转变. 编程语言本质上是与计算机通信的方式,并通过使用语法和语义告诉计算机要做什么.框架是汇集了一起完成任务的程序的集合,使编码更有效率,并且通常使程序员的生活更容易. 当然,二者绝不是对立的关系,只是编程社区中仍然存在一些争议:到底是应该自己从头开始编写代码还是使用各种框架简

  • 指南:想成为一个JSP网站程序员吗?

    任何Web开发人员需要必备的技巧主要有以下这些技术. 开发Web应用程序的技术已经变得更成熟.更复杂了.现在,构建一个Web应用程序不仅仅需要简单的HTML技术了.数据库访问.脚本语言和管理都是一个Web程序员需要具备的技术.让我们来看看要成为一个市场上受欢迎的Web开发人员都需要些什么技能吧. 自从CERN(欧洲粒子物理研究所),日内瓦附近的高能物理研究中心,在1991年发布了Web以来,Web技术已经从静态的内容和Common Gateway Interface(CGI)发展成servlet

  • 程序员开发项目是选择效率还是质量呢?

    本文作者系程序猿Daniel F Pupius,这是一篇他发表在Medium上的博文,讲述自己怎么在实际写代码的过程中,发现在效率和质量间做出抉择其实是个伪命题. 程序开发项目进行过程中,通常会冒出这样的困惑:应该选择效率,还是选择质量?很多程序猿都会有偷懒的思维,觉得把一些摸不清头绪.不知道怎么写的代码片段去掉,可以节省很多时间,更早完成项目计划. 其实过去几年中,我也是这么想的,但最近我开始意识到,这个问题的纠结之处不在于选择困难,而在于问题本身是个伪命题. 什么是"质量"呢?一般

  • 网站程序员如何应对web标准第1/2页

    作者:jxdawei jxdawei的blog:http://www.iwcn.net/ 本文讨论的是在web标准普及的形势下,网站程序员的定位以及如何与设计师配合开发符合web标准的网站项目.本文适合的读者是传统TABLE布局下分工不是非常明晰的程序员. 1:学习web标准,让你的工作变得更加简单. web标准是大势所趋,所以作为网站程序员.你必须洗脑,必须去学习web标准.去重新认识html标签,去了解如何让程序输出页面需要的代码. 比如: 上边是美工出来的效果图,下边是符合标准的程序代码:

  • 一个30多年编程经验的程序员总结

    在我30多年的程序员生涯里,我学到了不少有用的东西.下面是我这些年积累的经验精华.我常常想,如果以前能有人在这些经验上指点一二,我相信我现在会站得更高. 1.客户在接触到产品之后,才会真正明白自己的需求. 这是我在我的第一份工作上面学来的.只有当我们给客户展示产品的时候,他们才会意识到哪些是必须的.给出一个功能性原型设计远远比一张长长的文字表格要好. 2.只要有充足的时间,所有安全防御系统都将失败. 安全防御现如今是全世界都在关注的大课题.大挑战.我们必须时时刻刻积极完善它,因为黑客只要有一次成

  • 数据库设计的折衷方法

    作项目分析,数据库设计是一个很重要也很难的问题, 完全按照范式有可能不符合用户需求,不利于编程, 看来是具体问题具体分析,数据库设计是范式和需求的折中. 在上学时,没觉得数据类型有多重要,现在发觉了解数据类型 的具体内容也是很重要的,可以知道不同数据库之间的兼容问题 该怎么处理. 数据库设计技巧: 第2 部分- 设计表和字段 1. 检查各种变化 我在设计数据库的时候会考虑到哪些数据字段将来可能会发生变更.比方说,姓氏就是如此(注 意是西方人的姓氏,比如女性结婚后从夫姓等).所以,在建立系统存储客

  • 最有价值的50道java面试题 适用于准入职Java程序员

    下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最新版本,去掉了EJB 2.x等无用内容,补充了数据结构和算法相关的题目.经典面试编程题.大型网站技术架构.操作系统.数据库.软件测试.设计模式.UML等内容,同时还对很多知识点进行了深入的剖析,例如hashCode方法的设计.垃圾收集的堆和代.Java新的并发编程.NIO.2等,相信对准备入职的Ja

随机推荐