在之前遇到过的项目中,常常发现有的人对数据库中的表建的特别的随意,丝毫不考虑使用场景与网站在实际操作中的各种情况
比方说我们现在有一个社交网站要建立一个用户表 叫做db_user
现在这个表里边我们要存放 用户ID,用户名,性别,生日,上次登录时间 及 个人简介
我们举一个常见的反例
很多人都会这样建表有木有,更有甚者建表中除了ID一律varchar(60)
虽然利用上边的表我们也可以做到正确存储数据,但是如果从性能上来讲那么它就差很多
那么怎么样建表是正确的呢?
首先我们先来说一下开发中的建表原则:
在开发过程中,我们往往把频繁用到的信息,优先考虑效率,存放到一张表,不是经常用到的信息,我们更多的会考虑空间上的节省,放在辅助表中。有时我们对于常用的需要关联的信息,我们也会做冗余设计(虽然有可能违背我们课本中所学的遵循范式的建表原则),用来提高我们的检索速度(用空间换时间)
那么什么样的数据的查询效率高呢?
计算机中万物都是用二进制来存储的,所以我们越贴近底层的数据类型效率越高,如我们的int类型性能就远远要比varchar类型的检索速率要高。
定长的数据类型的检索要比变长的数据类型的检索速率要高,但是相对来讲可能会相应的牺牲一部分空间
那么我们再来分析我们上边的用户表
1.我们先分析那些信息的使用频率较高
我们可以打开我们的QQ的个人信息看一下
我们可以发现用户的信息我们并不是全部的查询出来,比如像个人简介这样的信息我们在这里就没有看不出来,所以我们优先考虑 用户名,性别,生日这一部分信息的效率
首先我们先看用户名:对于用户名来说我们不能使用数字类型,所以我们先把它设置成定长的字符串char(20)(假设我们的用户名不会超过20个字符)
然后是性别,我们知道性别除了男就是女,只有这两个状态,我们可用tinyint类型进行存储,相对使用varchar类型更加节省空间,同时在满足需求的情况下又提高的检索的效率。
生日的话呢我们在实际业务中可能会根据生日做一些计算,所以我们使用int类型的时间戳可能相对于使用date类型更加的方便一些
这样的话我们表中的用户名(char(20)),性别(tinyint 固定占1个字节),生日(int 4字节)都变成了定长
然后我们再看登录时间(datetime) 我们知道在数据库中,dateTime类型占位是8个字节,而int类型是占4个字节,我们完全可以用int来代替dateTime进行时间存储,而且int类型相对来说更接近底层,检索速率会更高
这样的话我们会我们就会发现 表里边除了个人简介之外全部成了定长,所以有的人可能会说了,我们是不是也要把个人简介也要改为定长,其实在我们仔细思考后就会发现,如果我们限制个人简介在1500字以内,但是我们在使用的过程中我们可能只需要存几十个字,那么我们把个人简介信息设置成一个char(1500)将会极大的浪费我们的空间,但是我们也不能因为这一个字段拖慢我们整体的检索速度,所以这个时候我们会新建一张表单独存放个人简介(前提是个人简介属于不经常操作的信息,例如QQ中的个人简介)
这样根据我们上边的分析,我们做出的表应该是这个样子的
db_user表
db_userIntro表