文档章节

数据库杂谈之:如何优雅的进行表结构设计

鱼煎
 鱼煎
发布于 2016/05/07 00:27
字数 1685
阅读 212
收藏 24

数据库表结构设计作为后端软件开发不可或缺的一环,是每个后端工程师都会经历的过程。笔者也多次经历过这样的过程,也尝试过多种不同的设计方,也从一些优秀的框架中学到不少,但并没有发现相关的文章对其进行总结。所以本文尝试把笔者看到的、学到的总结下来,希望对阅读本文的读者有所启发。

表结构设计主要有两个目的,一是让表结构更加的更具有表现力,做到数据库表的自描述,减少注释甚至不使用注释;二是满足系统效率和扩展性的需要,让系统性能更好,后期维护更简单。

本文主要探讨的是如何优雅的设计表结构,让人能够直观的从命名中窥探设计意图,传达设计者的设计目的,让团队成员达成共识,减少沟通成本。本文不讨论表结构设计对性能的影响,也不讨论数据库设计中的范式与反范式设计。本文将从数据库表的命名和字段的命名两个方面展开。

数据库表的命名

使用名词作为表名

仔细想想便可发现,数据库表中存在的所有数据都是现实世界各种操作的结果,它们有的是中间过程结果,有的是最终数据结果。不论怎样, 它们是一份一份没有任何动作的,静态的记录 。而表本身就是存储这些记录的容器,从这样的层面理解,表名应该采用名词的形式是完全符合逻辑的。

比如我们要设计一个存储用户邀请的表,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

title: varchar

content: text

created_by: integer

created_at: timestamp

通过把 user_id 替换为 created_by、create_time 替换为 created_at, 使得我们更容易理解对应的文章是被指定的人在指定的时间创建出来的 ,而不需要我们的多方猜测或者查阅文档,使得整个表结构的描述性更强。

时间区分当前时间和未来时间

英语中表时间的时候, 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 是指定的人被创建的,而不是凭空生成的。


本文转载自:

鱼煎
粉丝 15
博文 218
码字总数 40364
作品 0
深圳
技术主管
私信 提问
加载中

评论(2)

鱼煎
鱼煎
和你说的一样的,会去掉符号、改写单复数、前后单词首字母大写;
微脸盆
微脸盆
数据库字段与实体类属性一般是一一对应的关系,那你实体类属性如何命名?我通常会用creatorId,createTime,startTime,endTime这种风格。
删库跑路不怕,用mysqldump和mysqlbinlog进行数据恢复

前言 系列文章: 1.MySQL主从复制 2.OneProxy实现MySQL读写分离 3.MySQL数据库结构设计 4.MySQL基于GTID主从复制的杂谈 5.MySQL复制性能优化和常见问题分析 mysqldump全量恢复 1.创建数据库、...

cmazxiaoma
04/21
0
0
MySQL数据归档实战-python和pt-archiver的强强结合

作者简介:蓝剑锋 TCL高级DBA,MySQL&Oracle OCP,负责数据库架构设计、数据库自动化运维平台。微信:lanjian106103,个人公众号:DBARUN 一. 引言 前段时间在 优雅的使用pt-archiver进行数据...

ACMUG
2018/01/15
0
0
SQL查询优化——数据结构设计

本文部分内容会涉及mysql,可能在其他数据库中并不适用。本章节只针对数据库结构设计做讨论,查询优化的其他内容待续。 数据库设计及使用是WEB开发程序员必备的一项基础技能,在大数据量和高...

蜗牛奔跑
2016/11/24
5
0
数据库设计(一)——数据库设计

数据库设计(一)——数据库设计 一、数据库设计简介 按照规范设计,将数据库的设计过程分为六个阶段: A、系统需求分析阶段 B、概念结构设计阶段 C、逻辑结构设计阶段 D、物理结构设计阶段 ...

642960662
2018/03/17
0
0
基于 Spring JDBC 的轻量级 ORM 框架--sborm

一、SBORM 介绍 1、目前只考虑支持 mysql; 2、基于spring jdbc的上层封装,底层jdbc操作基于JdbcTemplate,对于使用spring jdbc的人会有一点价值,比较简洁的封装可以节省很多重复劳动,具体...

franticwind
2015/03/30
2.3K
0

没有更多内容

加载失败,请刷新页面

加载更多

10分钟详解Spring全家桶7大知识点

点关注,不迷路;持续更新Java架构相关技术及资讯热文!!! Spring框架自诞生以来一直备受开发者青睐,有人亲切的称之为:Spring 全家桶。它包括SpringMVC、SpringBoot、Spring Cloud、Spr...

我最喜欢三大框架
16分钟前
4
0
注册服务

列出所有服务[root@localhost ~]# systemctl list-unit-files[root@localhost ~]# systemctl status mysqld[root@localhost ~]# systemctl stop mysqld[root@localhost ~]# ......

jxlgzwh
19分钟前
0
0
解决jdk8 stream tomap方法报错:java.lang.IllegalStateException: Duplicate key异常解决(key重复)

List<User> userList = User.ME.loadList(users); if (CollectionUtils.isNotEmpty(userList)) { Map<Long, User> userMap = userList.stream().filter(Objects::nonN......

冰峰雪座
28分钟前
0
0
jdk中的一些命令

jdk中的一些命令 jps jstack jmap jstat jhat jinfo javap http://www.importnew.com/18398.html

晨猫
29分钟前
0
0
Bystack的高TPS共识算法

共识算法是分布式系统保证节点数据状态一致性的方法,在区块链的共识算法分POW(工作量证明)和POS(权益证明)两大类。第一类POW模式是在公链项目中运用的最广泛应用的共识算法,比特币长达10年...

比原链Bytom
30分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部