数据库设计的一些心得

  • 采用单一自增ID作为主键。

最近在研究一些开源项目,发现其数据表的设计都采用了单一的自增列的ID作为了表的主键。结合自己以往的经历,感觉这是一个非常不错的设计主张。

其特点包括:

(1)表设计风格的一致性,所有的表都按照同一风格设计,包括一些映射关系表(往往可以采用组合主键的表)。

(2)业务关系耦合小,表之间的依赖关系简单。这样的设计,通常会把业务逻辑关系控制放在业务编码的业务层去进行控制,使得开发人员可以把更多的关注点放在业务层代码的实现上,而不必过多考虑在数据库中存在的业务逻辑控制。

(3)为了性能的考虑,数据表设计并不完全遵从数据库范式的设计风格。

在以往做数据库设计时,经常因为业务问题,在自己的项目中出现多种类型的主键,什么自然键、代理键、组合键,经常混杂在一起,缺乏风格一致性,搞的业务对象耦合关系复杂,涉及修改和导入数据时,往往很难操作。

另外,因为之前使用过oracle的数据库,对其中的sequence情有独钟,因为可以让几个相关的数据表采用同一个序列,便于扩展某些同质的应用,比如不同的评论信息分属在不同的表中,但可以根据ID来进行相同的处理。后来在使用ms sql做数据库服务器时,也希望通过一个序号生成器的来模拟sequence的部分功能,开始应用时,感觉还不错,可在一次大批量导入数据时,却发现无法直接用批量导入的问题。另外,采用序号生成器时,对事务控制的依赖也会有所加大。

如果采用单一自增主键ID的设计方式,则可以比较好的解决自己之前所碰到的一些问题。

虽然在设计迁移时会碰到一些障碍,但在目前的各个数据库都可以找到比较好的解决方案。

  • 大容量字段单独存储。

SQL Server最小的存储单位是页(Page),一个页的大小是8K=8192字节。其中页头的大小是固定的96个字节,页头保存了页的编号、上一页ID、下一页ID、可以字节数等等关于该页的基本信息,剩下8192-96=8096个字节用于存储数据行和行偏移矩阵。SQL Server进行数据库读写操作的基本单位是页,如果一页中存放了更多的数据,那么对表进行扫描和查找时进行的IO操作将减少,从而提升数据库的检索性能。

为了提高数据库查询的性能,在表设计时可以遵循以下建议:

  • 主键尽可能的短,能用tinyint的就不要用 int,能用char(5)的就不要用成varchar(50)。
  • 计算好表列的长度,能够在一个页中存放5条数据的,那就不要将字段设置的太长使得一个页中只能存放3条或者4条数据。
  • 尽量将字段设置为不允许为NULL,因为NULL值在存储和数据处理时系统需要专门的处理,降低了性能。
  • 能够用固定长度的就不要用变长字段,比如身份证号就可以使用CHAR(18),而不应该使用VARCHAR(18)。
  • 不要在一个表中建立太多的列,如果一个实体的属性太多时可以考虑进行垂直分割,将常用的字段放在一个表,不常用的字段放另外的表,这样可以减小常用字段表中数据列占用的空间,使得一个数据页中存储更多的数据行。
  • 不要将大对象、长字符串和常用的字段放在同一个表中。同样还是出于性能上的考虑,比如有个产品表,里面有产品ID、产品名字、产品售价、产品图片、产品描述等字段,那么我们可以将产品ID、产品名字、产品售价这几个常用的而且占用空间小的列放在一个表,然后建立产品ID、产品图片、产品描述这样的表,通过外键约束的方式将大对象数据和长字符串数据放在另一个表中。

至于大容量字段是单独存储于一个表还是作为业务表的扩展表,则可以根据自身系统的因为特点来采用相应的方案。

  • 数据库设计时,要区分人、物、事,识别关键业务对象。

在进行数据库设计时,需要从业务需求中梳理出有哪些是业务对象(人、物),哪些是业务关系(事),哪些是关键业务对象。然后围绕着关键业务对象,进行业务梳理,找到关键业务对象间关系,找到关键业务对象从属业务对象间关系。这样做,可以将耦合紧密的业务对象及其从属业务对象集中起来当作一个盒子来看待,而整个业务系统的大局观则可以从关键业务对象间的耦合关系反映出来。通过这样的分解,从而把业务关系可以梳理出不同的层面来供不同的人员来理解和使用。

posted @ 2010-05-18 15:52  远去的河流  阅读(408)  评论(0编辑  收藏  举报