在做数据库设计时,咱们常常须要给很多表减少一个‘类型’ 字段,比方人的性别有‘男’, ‘女’,学校的类型有‘幼儿园’,‘小学’,‘中学’,‘大学’,汽车的类型有‘轿车’,‘suv’,‘mpv’等,这种字段的实质特点是它们蕴含 “无限个离散值”。
对于这种字段,应用enum数据类型是最合适的,mysql和PostgreSQL都有此数据类型。enum类型有这么一些特点:
1、在表中enum字段存储的理论是其程序值(整数),而不是字符串。
2、依照enum值做查找和比拟的时候,依照程序值来查找和比拟,而不是依照enum项的字符串。不过mysql在这个方面有个问题(见下文截图):与其某个enum项雷同的字符串做范畴比拟(>, <, >=, <=)时候,并没有依照程序值比拟,而是依照字面值比拟了。然而mysql在依照enum列做排序的时候,却也可能正确滴依照enum项的程序值来排序。
3、postgresql的enum类型须要事后定义好,而后在create table的时候应用该类型。这样做的益处是多个表能够应用同一个enum类型,不用屡次定义而导致不统一等问题。
4、能够对enum列定义索引,索引key排序也是依照enum程序值排序,并且索引key也是enum程序值(整数)。
上面的截图是应用昆仑分布式数据库做的示例。外面mysql的示例是应用昆仑分布式数据库的存储节点(mysql8.0.15)做的。
创立应用enum数据类型的表,而后插入数据。
对enum类型的列做范畴查找和等值查找,程序值决定enum项的大小关系。
依照enum类型的列排序时候,会依照其程序值而不是字面字符串 做排序。查问元数据表能够看到enum类型的元数据。
mysql的enum用法:能够做等值查找,然而范畴查找没有依照程序值而是依照enum项的 字面字符串 来比拟的,这样做其实是谬误的。
mysql中enum列的定义,依照 enum项 呈现的程序给每个enum项赋予 程序值,从0开始。
依照enum列排序时,是依照enum项 的 程序值来排序的。从元数据字典能够看到‘职级’这个enum类型的enum项的程序值。
插入更多行后,再次排序,依然是依照enum列的程序值而不是字面字符串 来排序的。
mysql对enum列也是依照程序值排序,然而与enum字符串做大小比拟时候无奈聪慧滴依照程序值来比拟。
在举例说明enum的用法之后,我列举一下不应用enum的数据库设计当中不好的设计方案。这些计划应该被摒弃,切不可模拟。
1、有人间接应用字符串类型,比方varchar(N) 类型的列,来存储这样的字段值,这样的问题是,有可能下层利用的谬误会输出意外的字段值,比方上例中学校类型字段,如果应用层数据处理不充沛,导致插入一行Rx.type = ‘大 学’,那么这样的行Rx也齐全能够插入到表中。于是当你查找 类型=‘大学’ 的行时候,就找不到Rx了。还有一个问题是空间利用率问题。在mysql和postgresql中,enum字段理论存储的是enum值的数值,通常会比存储字符串节俭空间,而且在查找和比拟时,数值比拟也比字符串比拟更快。
2、另有人会在db的表中应用数字来代表类型,而后在应用层实现数字与类型字符串的转换。比方上例学校类型中,用1代表‘幼儿园’,2代表‘小学’等,而后在应用层残缺这种数字与字符串之间的转换,向最终用户展现字符串,向db的对应字段中存入数字。这样做的问题是,减少了应用层开发的工作量和保护开销。构想前期须要减少更多类型值,还要批改应用层代码。而且,没有应用层代码,还齐全无奈了解字段值的意义(当然,能够减少正文阐明),影响数据的可读性。
从这里能够看出enum类型的几个长处:
1、数据校验,回绝非法值。
2、高效存储和计算。
3、数据可读性强,不须要依赖利用代码来解释。
4、不须要应用程序做任何数值解释和转换,升高应用软件开发和保护的老本。
所以,强烈建议数据库设计和利用零碎设计的时候,适当的时候应用enum类型。
KunlunDB我的项目已开源
【GitHub:】
https://github.com/zettadb
【Gitee:】
https://gitee.com/zettadb
END