设计: 关于建表我想说点什么

我先澄清一点,我建表之前确实看了看我本科的教材打算搞明白范式怎么在我这个表里怎么起作用。但是因为这是一个太小的工程,可能只用到皮毛。这边就不跟会建表的后端大佬理论这个事,请高抬贵键盘。我只是站在一个前端的角度试图让我还没怎么玩过数据库的同行理个思路。

一、怎么把数据整理成表

1.拆分源数据

以博客创建举例:

创建博客时你要存储的数据可能分这么两类:与博文本身相关的数据,与操作者有关的数据。

向下扩展可以得到:

(1)与博文相关的数据: 文章标题,文章内容,与文章相关的时间信息,文章分类(这是建立在总体设计有分类的需求时产生的)

(2)与操作者有关的数据:作者信息,访客信息(如果需要记录访客数据的话)

2.根据第一范式原则将其拆解

数据库表设计遵循三大范式的原则,最基础的第一范式原则就是让每个字段都不可再拆解,这称之为它的原子性。

比如与文章相关的时间信息,可以分成创建文章的时间和修改文章的时间,访客信息可以拆解成访客ip,访客数量,访客访问的设备信息。

关键原则是这个数据已经不能再向下拆分了,这一步就做完了,你就拥有了所有需要的字段。

3.根据第二范式,第三范式区分要创建几个表

第二范式指的是每张表里的字段都应与其表中的主键相关,第三范式要求这种关联是强相关以去除冗余,但具体还是要看业务需求,有的时候小的冗余反而会让你的操作更加方便。

举个例子解释一下:访客的ip与访客的关系是强相关,因为每个访客自带一个ip且可以标识唯一的访客;文章标题与访客无关(或者说你要分析访客爱看什么文章的时候才有关,我的需求中,它们是没有关联的),这个时候就要把这两个信息置于不同的表中。弱相关的意思就是有关联但并不紧密,这种数据通常可以拆分到不同表中充当不同功用,例如时间信息和标签信息,文章在创建之后才会有标签,它们本身有关联,但是中间又隔了文章信息,这种就可以拆解。

img

整理一下,第一张表是文章的所有信息(主键是文章标题),第二张是访客的所有信息(主键是访客ip)。第三个列出的内容再加一个文章标题可以拿来做根据分类查找标题的时间轴,当然这个也可以不拆分,直接在文章表里用。

二、字段的类型很重要

你创建的字段都应该有它的类型。很好想的一个就是时间,肯定要用时间特有的类型,另外访客数量用的肯定是数字类型,这些你就按你所想去做。但要注意的是,你给字段长度的时候要考量自己信息是不是可能超过这个长度,这个数据是否可以为空,你从前端拿来的格式是不是符合你自己数据库里存的格式。切记从数据的源头一路考虑到数据的存储,工程中间改动数据库的结构或者数据类型可能造成大量客户端服务端代码改动。

三、不同的设计方式会造成什么样的后果

每个人面对同一个工程的时候都不一定会建一样的表。数据库表设计的好坏通常在你开始书写调用代码时才能体现的较为明显。

举我自己例子来讲,开始的时候我是将文章分类信息与文章其他信息放在一张表中的,利用字符串类型存储,每个分类标签用逗号间隔。这样文章和标签的关系就是同表一对多,但是在针对文章单个标签的修改和删除逻辑时,这样的设计方式就很有问题,虽然很容易找到一篇文章的所有标签,但如果想找到想编辑删除的某一个标签,需要多次筛选。后面我做了分表的操作,将【标签,文章标题,创建时间,更新时间】作为新表元素创建,这个关系不同于之前的同表一对多,当修改文章时要跨表查询标签,文章和标签之间的关系是多对多。这样的虽然在数据上有一些冗余,查询时要相对麻烦,但是灵活性比较高,比较符合我工程的需求。

在改动表结构之后我对服务端的代码做了比较大的改动,所以也导致工程停滞了一段时间,所以在工程开始前尽量考虑全面一些再建立数据库表结构是很重要的。