数据库表结构设计

本文探讨了数据库表结构设计的重要性,强调了遵循数据库设计的三大范式以避免冗余数据。文章指出在设计时应注意按组件划分,减少组件间表的关联,采用领域驱动设计,并确保主键和外键的合理使用。此外,还提出了表设计的约定规则,如主键的存在、字段的单一含义、日期字段的使用以及避免复杂数据类型等。

在进行数据库的表结构设计的实操之前,应当好好了解一下数据库表结构设计的几个关键的问题:

为什么要学习数据库表结构设计

在实际的数据库开发中,需要将大量的结构化数据汇总到数据库表中,这时候不能鲁莽的开始设计单个数据库表,应当考虑几个问题:表名称如何命名,表中有哪些字段,各个字段的命名规范,字段的数据类型,字段的长度以及和其他的表之间的关联等。

数据库表结构的设计原则

数据库设计的三大范式,范式即关系型数据库中所要遵循的规则。

  1. 第一范式
    每一列的属性都是不可再分的属性值,确保每一列的原子性;
    两列的属性相近或相似或一样,尽量合并属性一样的列,确保不产生冗余数据。

  2. 第二范式
    保证数据库中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言),即一行数据只做一件事。也就是说,在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中;

  3. 第三范式
    需要确保数据库表中每一列的数据都和主键直接相关,不能间接相关,像属性之间有这样的关系:a->b->c是不符合第三范式的。

数据库表结构设计时应当注意的一些事项

  • 不应该针对整个系统进行数据库的设计,首先应当根据系统架构中的组件进行划分,针对每个组件所处的业务进行组件单元的数据库设计;不同组件之间对应的数据库表之间的关联应当尽可能减少,如果不同组件间的表需要外键关联,也尽量不要创建外键关联,而只是记录关联表的一个主键,确保组件对应的表之间的独立性,为系统或表结构的重构提供可能性。

  • 应当采用领域模式驱动的方式和自顶向下的思路进行数据库设计,首先要分析系统业务,根据职责定义对象。对象要符合封装的特性,确保与职责相关的数据项被定义在一个对象之内,这些数据项要能够完整的描述该职责,不会出现职责的缺失。并且一个对象有且只有一项职责,如果一个对象要负责两个或两个以上的职责,应进行分拆。

  • 一个表中的所有的非关键字属性都依赖于整个关键字,关键字可以是一个属性,也可以是多个属性的集合。不论哪种方式,都应当确保关键字的唯一性。在确定关键字时,应该保证关键字不会参与业务,并且不会出现更新异常,最优的解决方案为采用一个自增数值型属性或一个随机字符串作为表的关键字。

  • 领域模型中的每一个对象只有一项职责,所以对象中的数据项不存在依赖传递(第三范式)。

  • 由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关系,所以在领域模型中的对象存在主对象和从对象之分,从对象是从1-N或N-N的角度进一步完善主对象的业务逻辑,所以表以及表的关联关系不应该出现删除和插入异常。

  • 在映射后得出的数据库表结构中,应当再根据第四范式进行进一步修改,确保不存在多值依赖。

  • 表和表之间的关联应当尽量采用弱关联以便于对表字段和表结构的调整和重构。并且,数据库中的表示用来持久化一个对象实例在特定时间、特定条件下的状态的,只是一个存储介质,所以表和表之间也不应该用强关联来表述业务(数据间的一致性),这一职责应由系统的逻辑层来保证,这种方式也确保了系统对于不正确数据(脏数据)的兼容性。

  • 应针对所有表的主键和外键建立索引,有针对性的简历组合属性的索引,提高检索效率。

  • 尽量少采用存储过程,目前已经有很多技术可以代替存储过程的功能,例如“对象/关系映射”等

  • 当处理表间的关联约束所付出的代价超过了保证不会出现修改、删除、更改异常所付出的代价,并且数据冗余也不是主要的问题时,表设计可以不符合四个范式。四个凡是确保了不会出现异常,但也可能导致过于纯洁的设计,使得表结构难于使用。

  • 设计出的表要具有较好的实用性,主要体现在查询时是否需要关联多张表,并且还需要使用复杂的SQL技巧。

表设计约定规则

  • 表必须要有主键

  • 一个字段只表示一个含义

  • 总是包含两个日期字段:gmt_create(创建日期),gmt_modified(修改日期),且这两个字段不应该包含有额外的业务逻辑。MySQL中,gmt_create、gmt_modified使用DATETIME类型。

  • 禁止使用复杂数据类型(数组,自定义类型等)。

  • MySQL中,附属表拆分后,附属表id与主表id保持一致。不允许在附属表新增主键字段。

  • MySQL中,存在过期概念的表,在其设计之初就必须有过期机制,且有明确的过期时间。过期数据必须迁移至历史表中。

  • MySQL中,不再使用的表,必须通知DBA予以更名归档。

  • MySQL中,线上表中若有不再使用的字段,为保证数据完整,禁止删除。

  • MySQL中,禁止使用OCI驱动,全部使用THI驱动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值