数据库表结构设计做为后端软件开发不可或缺的一环,是每一个后端工程师都会经历的过程。笔者也屡次经历过这样的过程,也尝试过多种不一样的设计方案,也从一些优秀的框架中学到很多,但并无发现相关的文章对其进行总结。因此本文尝试把笔者看到的、学到的总结下来,但愿对阅读本文的读者有所启发。数据库
表结构设计主要有两个目的,一是让表结构更加的更具备表现力,作到数据库表的自描述,减小注释甚至不使用注释;二是知足系统效率和扩展性的须要,让系统性能更好,后期维护更简单。后端
本文主要探讨的是如何优雅的设计表结构,让人可以直观的从命名中窥探设计意图,传达设计者的设计目的,让团队成员达成共识,减小沟通成本。本文不讨论表结构设计对性能的影响,也不讨论数据库设计中的范式与反范式设计。本文将从数据库表的命名和字段的命名两个方面展开。微信
使用名词做为表名框架
仔细想一想即可发现,数据库表中存在的全部数据都是现实世界各类操做的结果,它们有的是中间过程结果,有的是最终数据结果。不论怎样,它们是一份一份没有任何动做的,静态的记录。而表自己就是存储这些记录的容器,从这样的层面理解,表名应该采用名词的形式是彻底符合逻辑的。数据库设计
好比咱们要设计一个存储用户邀请的表,invitation 就比 invite 更加的优雅。性能
相关表采用统一前缀翻译
咱们知道,大型系统的设计每每按模块或者子系统进行划分,一个一个模块的处理问题,保证模块间的低耦合,模块内的高内聚。数据库表设计也同样,咱们能够对相关联的表采用相同的前缀,使开发人员一眼看上去就知道哪几个表是相关的。设计
好比对于用户基本信息表、用户的详细信息表和用户的微信绑定表以下的命名更可取:事件
user
user_profile
user_wechat
本节先介绍几个比较通用的原则,使得字段的含义更容易理解,描述性更强,以后进行简单的总结分类,以便让咱们明白这些原则背后的逻辑。开发
使用动词被动形式+描述性后缀
经过前面咱们知道,数据库表中的全部记录都是静态的结果性数据,它是由必定的用户操做产生的。那么它是如何产生的?通过什么样的操做产生的呢?在解答以前先看一个例子,下面是一个简单的 article 表结构:
id: integer
title: varchar
content: text
user_id: integer
create_time: timestamp
这样的设计自己是没有问题的,目前用的也不少。这个设计主要的问题是没有体现出 user_id 与这篇文章的关系,须要通过必定的猜想和思考才能得出。create_time 虽然还比较直观,但没有体现出这篇文章实在过去的某个时间建立的。
而后咱们在来看修改后的设计:
id: integer经过把 user_id 替换为 created_by、create_time 替换为 created_at, 使得咱们更容易理解对应的文章是被指定的人在指定的时间建立出来的,而不须要咱们的多方猜想或者查阅文档,使得整个表结构的描述性更强。
title: varchar
content: text
created_by: integer
created_at: timestamp
时间区分当前时间和将来时间
英语中表时间的时候, at 通常跟一个时间点,而 in 有表示在将来的某个时间以内的意思。结合起来,笔者倾向于用 at 表示过去或者如今的时间,而用 in 表示将来的时间。好比日历中的 event 有开始时间和结束时间的概念,我以为以下的命名是比较合理的:
starts_at 事件的开始时间,相对 ends_in 它属于当前时间,采用 _at 后缀
ends_in 事件的结束时间,相对 ends_in 它属于将来时间,从用 _in 后缀
其余咱们比较经常使用的好比 created_at、updated_at、expires_in 都属于这种类型。
使用第三人称单数
当咱们采用动词+介词的时候我更倾向与使用第三人称单数,由于字段描述的这个实体是单数的,经过使用第三人称单数,咱们能够天然语言的方式表达出须要的意思。好比以 event 为例,翻译成英语是这样的:
The event starts at 2016-05-05 12:00:00
彻底符合英语的语法,也表达了咱们想要表达的意思。
区分单数与复数
单数与复数主要是对字段内容的描述,好比通知(notification)有接收人这个字段,若是咱们须要通知可以发送给多我的,那么 receivers 这样的字段名称明显好于 receiver,由于 receivers 体现了通知能够发送给多我的这一个事实。
前面从四个原则出发介绍了如何让字段更具备描述性,简单总结下来我以为从语义上来讲,字段能够分为两种类型:描述性字段和动做性字段。
描述性字段是对对应数据库记录(或者说实体)的补充说明,好比以人做为实体,那么人的身高、体重和血压就属于这类描述性字段。
描述性字段若是是动词+介词的形式,动词须要采用第三人称单数的形式,好比 starts_at。而后根据字段的内容,若是内容有多个元素或实体,咱们须要使用复数,不然使用单数形式。
动做性字段不只能对所属实体进行补充说明,还能对这个实体的所涉及操做有所描述。好比咱们有 article 这个实体, article 的 created_by 和 created_at 就属于动做性字段,由于它不只表达了 article 的建立者和建立时间这层信息,它还表达了这个 article 是指定的人被建立的,而不是凭空生成的。