沙龙晃荡 | 3月31日 京东、微博、华为拭魅战专家与你合营商量容器技巧实践!
MySQL的 列举(ENUM)类型 是法度榜样员群体中的一个评论辩论热点。乍一看,我们可以经由过程列举类型,很好地将记录值限制在许可范围内。一个典范的例子是,一个具有字段名称为“大年夜陆板块”的数据表:每一个国度位于一个大年夜陆板块,而这些大年夜陆板块不太可能经常变更。当然,或许一天北美板块会与亚洲板块碰撞形成北美亚,但即便你的数据库可以或许延续应用到那个时刻,起码你也不须要研究怎么去重构你的数据表,那将是当时的开辟者要做的工作。
言归正传。如不雅,应用ENUM是独一 一个,可以或许代表某一个国度属于哪个大年夜陆板块的选择,那我们大年夜可进行下一步,去辩论诸如NoSQL的好坏、Git和SVN孰强孰弱、你爱好的框架有哪些缺点这些其他的问题。但这里有一个广泛实用于实现列举的最佳实践:
至今都没有一个可以加倍明智地改变ENUM类型字段的办法,这也是我们的常态。在我们的“国度、大年夜陆板块”例子中, 更改“国土面积”会出现什么情况?我们没有预感到这个属性, 但也要既来之则安之。应用关系表设计,我们可以随便马虎地拓展“大年夜陆板块”这个数据表,各类方法为其增长我们想要的数据和字段 。ENUM?快别说了。
所以,关系表也可以知足列举的实现。下面就来看看,ENUM的”八宗罪“到底是什么:
1. 数据被缺点对待
男、女;师长教师、夫人、蜜斯;非洲、亚洲,等等。这些人们应用作为ENUM类型字段的短词称为数据。当你应用一个ENUM类型字段, 技巧上看,是你将数据抽离出来 (对应到实际数据表时), 放到一个自力的地位(一种数据库的元数据,具有准肯定义字段)。 这不合与束缚数据类型,如我们平日的做法:数值型字段只能存储整型数据,或者日孚型字段不克不及为空——这些都没有问题,并且还十分重要。应用ENUM类型字段时,我们实际上是保存部分数据 去作为 这个数据模型的一个特点信息。简而言之, ENUM类型字段破坏了范式请求。这也许看起来十分“学院派”或“陈腐陈腐”,但这恰是以下各类“罪恶”的泉源。
2. 更改ENUM类型字段,价值很昂贵
永恒不变的是, 每次你创建ENUM类型字段的时刻都说:“这个字段弗成能变的”。仁攀类广泛欠缺顾全大年夜局的才能,猜测上更是糟糕,其如研发部的新产品线、贵司新的航运筹划、北美板块碰撞亚洲板块。
应用ALTER TABLE去修改┞符个数据表的ENUM类型字段,是十分消费资本的。如不雅将ENUM('red', 'blue', 'black') 改为 ENUM('red', 'blue', 'white'), MySQL 须要重构全部数据表,并且检索 所稀有据去检查 'black'这个无效值。 MySQL 是真的蠢,它确切会在你每次增长一个新的ENUM值时都这么做的!(传言将来会处理ENUM类型字段的效力问题,但我对其受看重程度深表困惑。)
全表重构在小型数据表中可能没有那么苦楚,但在海量数据的情况下可能会导致资本被锁逝世很长很长一段时光。如不雅你应用关系表去替代ENUM类型字段,改变列举集合只不过是应用INSERT、UPDATE和DELETE,比较来看真是滑稽。
很重要的一点,当更改ENUM类型字段的列举集应时,MySQL会转换随便率性已有但不存在于新的列举集合中的记录值为''(空的字符串)。应用关系表,在更改和删除列举集应时会灵活很多(下面会提到)。
3. 几乎无法给接洽关系数据添加额外的属性
另一种极妙的灵活性表如今关系表的拓展便捷性上。一个简单的标记位字段即可表示这个“列举值”是否可用。所以,当你的公司不计算发卖黑色的装潢品了,你只需在“黑色”所对应的_isdiscontinued字段中做个标记即可。并且你依然可以萌芽到已售的色彩(译者:指的是,ENUM的修改会导致原有,而如今已经没有的值变为空字符串,数据掉去了部分特点),同时你那些黑色装潢品的订单依然可统可计哦!ENUM,你要不要尝尝?
4. 获取ENUM全部可能值,很麻烦
一个很常见的需求是,将数据库中存在的数据显示在可拖拽列表中,例如:
启悠揭捉?格模式,至少在你插入一个不存在的ENUM值时会申报缺点。不然,只会简单地出现一个警告,继而该值被设置为一个空字符串""(列举索引为0)。抄标记:如不雅你设置了IGNORE,缺点依然会被忽视。
结论
选择色彩:
红 蓝 黑
如不雅这些数值存储在一个名为‘colors’的数据表里,你所要做的仅仅是:SELECT * FROM colors,如许即可动态地令数据地显示在可拖拽列表中。你可以添加或者改变color关系表中的色彩,并且,你那酷炫订单的色彩可选项会主动更新,真了不得。 (译:此处所举例子,应等同于:“经由过程后台治理,可以限制前端用户某类型数据的可选项。”如许的功能。)
回到ENUM上:你要若何获取全部的列举值?你当然可以应用ENUM值搭配DISTINCT去萌芽(译:等于萌芽ENUM值互相不雷同的数据,等于应用DISTINCT的独一性去萌芽ENUM),但如许也只会返回确切应用过,并存在于数据表ENUM字段可选值中的ENUM值,而不是所有可能的值。你也可以萌芽INFORMATION_SCHEMA然后经由过程代码解析返回的数据,去找到你想要的ENUM的所有值,但这美满是画蛇添足。事实上,我依然没有发明,有任何兼顾了优雅与原生的SQL方法,可以获取ENUM类型字段的所有值。
推荐阅读
沙龙晃荡 | 3月31日 京东、微博、华为拭魅战专家与你合营商量容器技巧实践! >>>详细阅读
本文标题:MySQL枚举类型的“八宗罪”
地址:http://www.17bianji.com/lsqh/40788.html
1/2 1