首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL枚举vs.整型

MySQL枚举vs.整型
EN

Stack Overflow用户
提问于 2014-10-22 22:23:54
回答 3查看 12.5K关注 0票数 13

我有几个表的列既可以是ENUM类型,也可以是INT类型。我倾向于总是使用整数类型,假设基于它执行搜索会更快。

例如,我的一个表有一个列:StatusType,它只能有4个可能的值:CompletedIn ProgressFailedTodo

我没有将上面的字符串存储为ENUM字符串,而是将它们存储为:

1234。然后在我的PHP代码中,我有常量变量来定义这些值,如下所示:

代码语言:javascript
复制
define('COMPLETED', 1);
define('IN_PROGRESS', 2);
define('FAILED', 3);
define('TODO', 4);

现在我的问题是,我这样做是正确的,还是应该将其更改为ENUM类型,并在查询中使用字符串进行比较?我还有许多其他的列,它们只能有一组最大4-5可能值。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-10-22 22:31:58

这篇评论太长了。

枚举值在MySQL中看起来真的很酷,但我并不喜欢它们。它们被限制为255个值,所以如果您决定添加更多的值,那么您可能会遇到限制。此外,正如您所描述的,您需要将应用程序代码中的值与数据库中的值同步--这似乎有潜在的危险。

此外,它们会使未来的某些更改变得更加困难。例如,其他数据库不支持枚举。而且,如果您想添加多语言支持,在数据库的数据类型定义中嵌入代码有点难以处理。

更标准的方法是一个或多个引用表,其中使用join来获取值。您可以使用一种混合方法,即在数据库中使用引用表。然后,您可以将引用表加载到应用程序中,以获得从数字到字符串的映射,这样就可以避免代码中的联接。

票数 16
EN

Stack Overflow用户

发布于 2014-10-22 22:36:04

你说对了一半。从性能的角度来看,枚举非常糟糕:MySQL Enum performance advantage?

也就是说,将INT的定义绑定到您的代码也不是一件好事。理想情况下,如果您遵循正确的数据规范化模式,您应该在另一个表中定义数据库中的INT的值,并使用定义的索引作为赋值的值。

请参阅:http://en.wikipedia.org/wiki/Database_normalization#Normal_forms

这样做的原因是这样数据是可移植的,并且不需要代码库读取它就很有用(您可以通过执行join轻松地转储Excel的CSV )。

神速。

示例SQL:

代码语言:javascript
复制
SELECT *, state.name AS state FROM students
JOIN states ON student.state_id = states.id

只是为了得到州的名字。

或者要进行筛选:

代码语言:javascript
复制
SELECT * FROM students
JOIN states ON student.state_id = states.id
WHERE state.name = 'Maine' OR state.code = 'ME'

是的,奇怪的例子,但是想法是INTs很小,而VARCHAR是...变量...存储'Maine‘,而不是'16’,加起来超过百万行。此外,INT上的索引比VARCHAR快得多,所以你的查找速度也会快得多。特别是如果你天生就知道这个数字,并且在没有JOIN的情况下构建你的查询。这并不是一种常见的做法,但如果您想做一些更快的事情,并且可以确保假设值的有效性,则可以这样做。

票数 4
EN

Stack Overflow用户

发布于 2014-10-22 22:53:38

首先,我建议使用@GordonLinoff的答案。他对ENUM类型的看法与我的一致。它似乎没有任何真正积极的东西去做。我将此作为单独的答案添加,因为它在DB架构中经常被忽略。

戈登的回答,以及我对它的补充评论表明,规范化是一条可行的道路。将整数键存储在大表中,并将值存储在单独的表中。每个键/值对都有不同的表。对于95%的应用程序来说,这是正确的方法。无论如何,我都会避免在PHP中存储您的值。无论何时需要添加新的键/值对,都必须编辑代码,这是应该避免的。

您说这个表主要是被读取的,所以我认为考虑对数据进行反规范化是很重要的。我仍然不建议ENUM,因为我认为数据验证/限制应该是前端的功能,而不是数据库的功能,但是您可能会发现在主表中存储实际值而不是键更有利。连接对于读取应用程序来说代价很高,因此将值直接粘贴到要从中读取的表中,并对它们进行适当的索引,将使所有内容保持快速运行。

通常,当我们处理的应用程序是事务性的(写入),但有报告(读取)的需求时,我们会优化写入并高度规范化模式,但为了满足在报告端快速读取的需求,我们会在严重非规范化的单独表中重写数据。我们尝试将尽可能多的字段打碎到一个表中。通常将键和值都存储在同一个表中。这会产生大量丑陋的数据,但读取速度要快得多。

与大多数DB模式练习一样,您必须做适合您的应用程序的事情。这通常是一个平衡相互冲突的需求和牺牲速度以求理智的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26509801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档