前言
之前在文章《学员问答精选 – 1 – 数据库表拆分》中提及过一个数据库的设计问题。今天,微博上的@火丁日记 说:
表里有一个 status 字段,用来表示数据的状态,比如订单的已付款,已关闭等。以前我习惯把它定义为 INT 类型,但是慢慢的,我就记不清楚 1,2,3 到底指的是什么意思了,也想过用 ENUM 类型,但是不方便扩展,最后,我觉得直接用 VARCHAR 类型算了,去它的三范式。
百家争鸣
- 一些网友赞同使用varchar
- 一些还是觉得应该enum
- 一些觉得最原始的int是最好的
- 一些觉得要用字典表
各种考量
其实,一个字段类型的考量,主要包括:
- 准确性/精确性:必须能满足业务需求,不能丢数据,溢出等
- 性能:一般来说,int的运算比varchar要快
- 空间:尽可能占用最少的空间,一条记录浪费1字节,10亿记录就浪费1GB空间了
- 辅助性:譬如方便功能上的排序、方便开发人员记忆等
如果要为开发人员着想:
- 数据库里,表的字段可以添加描述,譬如0: Pending, 1. Paid, 2: Processing, 3: Delivered, 4: Cancelled
- 如果不满足,那可以用char(1),26个字符足够表达各种状态了吧?不够就char(2),再不行就char(3),主要是省空间。为什么不用varchar(n)而用char(固定数值)?因为varchar(n)要运算做各种trimming,起码在SQL Server里,譬如len()就是后面空格去掉后的长度,和datalength()不一样。这个一般是单词的首字母,记起来比int舒服些。我发现一些公司就是这样做的。
如果要追求节省空间,完全可以用tinyint甚至varbinary,毕竟1个字节有8位,一般订单也就那么几个状态吧?
首先,如果用varchar,那么要考虑:
- 你这个状态的值,是放英文还是中文?你的产品是否全球化的?
- 如果是放英文,那你还是需要本地化。
- 而且,既然要本地化,就没必要放完整的单词,char(1)便可,原因参考上面。
如果使用int,那么要考虑:界面文本显示,开发人员友好。
如果要考虑界面显示如排序等,一般来说,界面需要先根据条件过滤出来某种状态,但是,如果你的业务逻辑就是要同时显示多种状态的数据,这要考虑目标数据只是已经在界面的,还是在数据库的:
- 界面:那数据库的类型还是最精简的varbinary(1),在界面对值进行解释然后根据解释出来的规则进行排序
当然,有些业务系统会使用字典表,相当于外键,如果返回结果的时候就join,这里会比case xx when 1 then ‘某状态’ 的效率要差些,而且字典表还是需要做语言本地化的。
总结
其实,不管用哪种方案,都没有完美的,还是应该具体业务需求来。
爆栈之旅
是否想技术水平快速提升?是否希望快速成为公司的技术骨干?
核心价值
-
把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
-
针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
-
解答各种技术问题
-
为公司提供技术解决方案
请查看本站右边的信息联系我。
版权所有
所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。