最近公司启动了一个新项目,老大将表的设计工作交给了我来完成。所以也趁这个机会总结一下关于Mysql表的设计,字段类型的选择以及如果合理规范建立索引等。就当做是对原有知识的总结归纳吧。
关于表的设计
首先表的设计肯定是围绕具体的业务来实现的,所以在设计表之前,应该先将产品需求进行梳理一遍,对每一个业务功能实现的可行性进行评估,对于业务逻辑上不清楚或者有模糊的地方应该跟产品进行探讨确认具体的实现方案。不管怎样,我们在动手设计表之前,一定要对业务熟练。然后在根据业务,确认要哪些表,表中需要哪些字段。至于在很多理论书上说的数据库表设计的三范式之类的东西,我觉得在具体实施时,并不需求那样去死记硬背这一套理论,在设计表的过程中,我觉得应该要以业务为驱动,在思考这块业务代码的大概实现时,觉得这块功能需要哪些表,表中需要哪些字段, 比如说有些关联表的字段,我们是否可以对该字段进行冗余处理,这样能减少我所要查询的表数量。当你这种思路为驱动去设计表的时候,你会发现你的表其实已经符合所谓的三范式了,在这里再回顾下数据库的三范式:
范式一,列的原子性就是一个列尽量只存储表示当个含义的字段,如果日期,地址;我们应该将其拆成两个列来进行存储。
在范式一的基础上,二范式规矩要有一个唯一列来关联该记录保证当条记录的唯一性,这里我们在实际规程中都会为一张表设计一个主键,同时让其为自增长,将主键的值交由数据库去管理。
三范式是指,在二范式的基础上。一张表中涉及的内容尽量保证职责的单一性,比如用户member表,在该表中我们应该就只是记录与描述用户的相关字段,如果昵称,账户,头像等等,而想用户钱包,用户积分等可以独立成另外的两张表,然后通过设计一个外键值来关联上member主表。
关于表的设计,这里再总结一下,表的设计是在业务实现下为驱动的,表的设计应该尽量保证原子性(字段的原子性,表的单一职责性)这样便于业务的扩展,以及尽量减少大表的出现。即使时关联表之间,我们也可以根据业务的需求允许字段的适当冗余,减少关联表的查询次数。
关于数据类型的选择
只有熟悉Mysql数据类型的前提下,我们才能在这些类型中选择出合适最优的数据类型。Mysql支持的数据类型还是比较丰富的,这里我们再来回顾梳理下Mysql的数据类型
整数类型
tinyint,smallint,mediumint,int,bigint 分别使用的 8,16,24,32,64位存储空间。这里做个解释 ,
比如8位存储空间是指它的存储范围是 -2^(8-1) ~ 2^(8-1)-1 ---> -128 ~ 127
这里还有一个unsigned(无符号)属性选择,如果使用该属性则表示该字段值不允许负数,这样使得它表示正数值上限大致挺高了一倍,还是上面这个例子,使用了该属性后它的范围将是0 ~ 255
由于有符号和无符号使用的是相同的存储空间,并具有相同性能,因此可以根据具体的需求去选择就好了。
Mysql 可以为整数类型指定宽度,如果int(11),相信很多人在看表时都有看到这样的写的,但是它到底有什么实际作用呢?
首先先说明一下,这样写对大多数应用是没有意义的,它并不能限制值的合理范围,不管你在空号里填任何数值,int的存储空间都是32位。只是规定了客户端用来显示的字符个数。对于存储和计算来说,int(1)和int(20) 是相同的!
字符串类型
Mysql 支持多种字符串类型 varchar char
varchar 可变长字符串,对于要存储的值的字符长度不一的情况下,可以变长字符串更加节省空间,因为在存储时只使用必要的空间进行存储,当也有例外,比如的表是使用 ROW_FORMAT = FIXED 创建的话,每一行都会使用定长进行存储,这样会很浪费空间。
这里我们要知道一点 varchar在进行存储时,要使用额外的 1到2个字节进行长度的记录,如果列的长度使用小于或等于255的字符长度,则是使用1一个字节,大于255的长度将使用2个字节。
char 固长字符串,char适合使用存储很短的字符串,或者说所有的值都接近于同一个长度,列入可以用来存储密码的MD5值
BLOB 和 TEXT类型
ENUM 类型
如期和时间类型