请教一下关于 MYSQL,有一个订单的状态字段,用什么类型来设计比较好。

4 天前
 go522000
我现在数据库是使用 5.7 版本,但不熟悉 MYSQL ,所以习惯沿用以前旧的习惯。

以下为我的作法,感觉很不合理,希望学习一下。

比如:

state int ( 2 ) ,表示:0 待支付,1 已支付,2 已发货...6 交易完成

然后这个字段用 MYSQL 的注释把 123 这些表示什么注释好。

或者增加一个新的字段,把不同的状态的名字存储起来,比如:

state_value varchar ( 10 ) 。 用来记录状态的描述

大概这样设计。



然后就会遇到一些问题,假设未来增加一个备货中的状态,这个状态在 1 与 2 之间,就会很为难,那么在最后面增加一个 7 备货中,很奇怪的样子。

-----

搜索了一下,5.7 已经支持 JSON 格式了。

那么未来新的项目是否可以设计为:state json 这种类型,把状态 ID 与描述一起存进去,比如:{state:1,value:'PAY_SUCCESS',description:'已支付'}

类似这种方式?这样会不会在未来遇到排序很卡或者不好搜索之类啥的,影响非常大?

或者,是否可以升级到 8.0 版本,支持 ENUM 类型?

ENUM 索引会不会更快点?

数据库小白,求指点。
1948 次点击
所在节点    问与答
36 条回复
dcsuibian
4 天前
直接存字符串,对运维最友好
kk2syc
4 天前
加个 7 最方便,不要代码洁癖
Cu635
4 天前
感觉是要么就是只微调,不大动直接加个状态 7 ,不用管奇怪不奇怪了;要么大升级,“是否可以升级到 8.0 版本,支持 ENUM 类型”这种最合适,从根子上就不会奇怪的做法。
nzynzynzy
4 天前
有个客户的系统设计是 100 ,200 ,300…900 。这样你可以先用 100 ,200 ,等中间有了居间的再用 130 ,再精细还有 132 、133…感觉很合理。
pweng286
4 天前
@nzynzynzy 还真是.
coderYang
4 天前
@nzynzynzy 学到了,还真是,类似于 http 状态码一样的设计
Bylinz
4 天前
其实 1 2 3 4 只是你觉得的顺序,对程序来说,这随便什么都行。
如果程序早期的定义看起来不舒适,可以通过文档弥补。
不建议重新发明创造,因为你新加的东西也不一定能满足以后的需求,稳定才重要。
go522000
4 天前
@nzynzynzy 谢谢,是个好主意。
Suaxi
4 天前
同四楼大佬的做法,部分场景下排序字段的值我们这边也是这样设计的,中间间隔 10
b821025551b
4 天前
1 、int (2 )还是很大,MySQL 中 int 后面的只影响显示,用 tinyint 更好;
2 、1->2->3 和 1->8->5 只是你理解的顺序不一样,对于程序没什么区别;比如一个审核流程,正常可以 1->2->->3->4->5 ;但是走到 3 是不是可以驳回到 1 ,或者是不是可以跳过 4 到 5 ,或者 3 之后 4 和 5 可以同时审核
3 、不要用枚举!不要用枚举!! ENUM IS EVIL!!!
icemanpro
4 天前
@b821025551b 用枚举有什么问题?
z1829909
4 天前
直接用英文字符串,看见 state 就知道啥状态,不用在脑子里维护一个 map ,也不用代码里整注释。
Rache1
4 天前
@icemanpro #11 因为 MySQL 的枚举比我这个表情还滑稽
akira
4 天前
增加一个 7 备货中,很奇怪的样子。 // 不要有代码洁癖。。保持文档更新即可。。
b821025551b
4 天前
@icemanpro 严格模式下无法插入新的条目,想新增需要 alter table ;弱类型语言(这里特指 PHP )以及或者菜鸡一个不注意搞混了 insert xxx values(1) 还是 values('1')就炸了;与其它数据库对接不兼容,说到这里这里还有个不建议的是 UNSIGNED 属性(当然只用 mysql 的话倒是个 feature ,比如用 int 型可以直接存 ipv4 )以及一大堆问题随便搜搜就能看见
adoal
4 天前
数值类型只有作为基数(表示数量多少)和序数(表示先后顺序)使用时才有大小的语义。作为枚举类型的值,没有大小语义。

你可能以为,一个业务流程状态是序数,因为你很清楚流程是一路流转下来的。但实际上的流程,中间可能有分支、回转、跳跃。比如因为有特殊要求中途补付一些钱,比如物流弄丢了重新发货。这里每个节点使用的数字,只是为了把这个节点和其它的区别开,并没有任何大小的意义,所谓的 1 与 2 之间,只是莫某个节点与另一个节点之间,1 不是 1 ,2 也不是 2 。

换个角度想,如果用文字类型来描述,难不成能你也要让业务流程中的每个状态的名字恰好是按字典顺序从小到大?为什么用数值类型你就要有这种追求呢?
adoal
4 天前
至于 eunm 会不会更快,当然是不会。类型系统的完备性,不是为了性能,而是为了有更严谨的数据一致性约束。也就是减少程序的 bug 。但有些人认为这是多余的负担。
javapythongo
4 天前
直接用字符串
sujin190
4 天前
@go522000 他这个就是最佳最标准案啊,除了他说的,还有更重要的是,任何业务逻辑场景都分为住流程和细节,细节会随着业务流程变迁,但是主流成一般在一开始就可以确定,所以百位一般会进一步用来区分主流程节点,十位区分二级节点,就算一开始无法完全确定有几部主节点,但是大概分几部还是可以确定的,那么应该把 0 到 9 整体规划到几个大步骤去,而不是直接连续,这样就算主步骤一开始没有设计全也可以再加,其设计过程也是业务流程分析过程,既表达清楚又逻辑清晰,业务流程迁移方便也兼容性好,而且查询和逻辑规划也更容易
sagaxu
4 天前
代码中用 enum 类型,DB 中存 varchar 。

文本描述比数值更直观,你不用老是翻代码或者找注释去想 5 是什么。状态区分度不高,并不适合用于索引,所以对查找性能损失也不大。每条记录增加几个字节的存储,也不会带来很大的存储开销。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1095729

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX