一个表都有哪些字段,或怎么定义字段,这个没有固定的答案。表结构设计完全跟着业务需求来,随着经验的丰富,才能随手就设计出不错的表结构来。
在设计表时楠神给大家做些建议:
一、保持第一个好习惯,就是在设计表名时要加前缀,这样在用Navicat查看时会很方便。
就像上面一个数据库里放了两个系统的表,一个是“nbl”开头,一个“stb”开头。在“nbl”里,如果是跟会员有关系的可以加个“member”前缀,这样又可以很好的区分开来哪些是跟会员有关系的表。
这样的好习惯可以让表很有结构感,不至于一眼看上去很混乱。
二、保持第二个好习惯,在设计每个表时,都要有个主键ID,就是每个表都把主键命名为“id”。
不要小看这样的细节,命名很规范的话会让代码变得简洁,通用性好。还有一些字段,如非用户表的用户ID可统一为uid、类型统一为“type”、状态统一为“status”、添加时间统一为“add_time”……
三、保持第三个好习惯,勤加注释。楠神改过外包公司写的程序,最想骂人的地方就是表里一点注释都没有,根本不知道每个表的字段都是什么意思。有些字段我还能猜出来,可有些表示“状态”或“类型”的int字段,我得使劲的看代码,从代码中找到“1”代表什么,“2”代表什么……
简直无语,很多时候是没有什么技术文档。不是说我们写完一个项目,还要写一个手册供后来程序员去看,根本没时间写什么手册。所以大家一定要有“勤加注释”的好习惯,不至于我们写的代码、设计的数据表成为一个只有本人才能读懂的“死作品”。(只有自己能读懂的代码不要觉着挺骄傲的,只有烂代码才能自己读懂)
不加注释,有时候自己都不知道三个月前写的代码是什么意思。注释也是给自己看的。
四、能用整数型就不要用字符串型,能用char不要用varchar,能用varchar就不要用text。如果字段中有text类型字段,在select时如果不获取此字段最好不要用*把它一块获取到。多说一下,当然不光是text类型,在select时直接精确获取某几个字段比直接用*要好的多。
五、涉及参与计算的时间值,最好用int类型,也免得从MySQL获取了时间值还得用strtotime函数转成整数。如果只是做显示的时间值,可用MySQL的时间类型。
六、适当拆分表。也就是垂直分割表。
有些时候,我们可能会希望将一个完整的对象对应于一张数据库表,(比如会员表,就想着把每个会员该有的属性信息都存于一张表里)这对于应用程序开发来说是很有好的,但是有些时候可能会在性能上带来较大的问题。
当我们的表中存在类似于 TEXT 或者是很大的 VARCHAR类型的大字段的时候,如果我们大部分访问这张表的时候都不需要这个字段,或者有些字段更新频繁,有些字段不怎么更新,我们就该义无反顾的将其拆分到另外的独立表中,以减少常用数据所占用的存储空间。这样做的一个明显好处就是每个数据块中可以存储的数据条数可以大大增加,既减少物理 IO 次数,也能大大提高内存中的缓存命中率。
七、定义字段时最好加上not null属性,就是不让字段插入null值。
就像上面的表,楠神所有字段都加上了“not null”。
“not null”意思不能为空,是不是字段不能插入空值,比如空字符?
答案当然不是。
首先,我们要搞清楚“空值” 和 “NULL” 的概念:
1、空值是不占用空间的。
2、mysql中的NULL其实是占用空间的。
打个比方来说,有一个杯子,空值代表杯子是真空的,NULL代表杯子中装满了空气,虽然杯子看起来都是空的,但是区别是很大的。
建议大家都加上“not null”,如果不加MySQL会让字段默认值为null的。
说说null的都有什么影响:
1)NULL 要占用空间,所以mysql在进行比较的时候,NULL 会参与字段比较,所以对效率有一部分影响。
2)而且B+tree索引不会存储NULL值的,所以如果索引的字段可以为NULL,索引的效率会下降很多。
3)不知道什么样的情况下,null有时会转成字符串“null”,可能是恢复数据时吧,楠神看过一些数据库里面存了好多字符串“null”。这都是由null引起的。