我有几个表的列既可以是ENUM类型,也可以是INT类型。我倾向于总是使用整数类型,假设基于它执行搜索会更快。
例如,我的一个表有一个列:StatusType,它只能有4个可能的值:Completed、In Progress、Failed、Todo。
我没有将上面的字符串存储为ENUM字符串,而是将它们存储为:
1、2、3、4。然后在我的PHP代码中,我有常量变量来定义这些值,如下所示:
define('COMPLETED', 1);
define('IN_PROGRESS', 2);
define('FAILED', 3);
define('TODO', 4);现在我的问题是,我这样做是正确的,还是应该将其更改为ENUM类型,并在查询中使用字符串进行比较?我还有许多其他的列,它们只能有一组最大4-5可能值。
发布于 2014-10-22 22:31:58
这篇评论太长了。
枚举值在MySQL中看起来真的很酷,但我并不喜欢它们。它们被限制为255个值,所以如果您决定添加更多的值,那么您可能会遇到限制。此外,正如您所描述的,您需要将应用程序代码中的值与数据库中的值同步--这似乎有潜在的危险。
此外,它们会使未来的某些更改变得更加困难。例如,其他数据库不支持枚举。而且,如果您想添加多语言支持,在数据库的数据类型定义中嵌入代码有点难以处理。
更标准的方法是一个或多个引用表,其中使用join来获取值。您可以使用一种混合方法,即在数据库中使用引用表。然后,您可以将引用表加载到应用程序中,以获得从数字到字符串的映射,这样就可以避免代码中的联接。
发布于 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:
SELECT *, state.name AS state FROM students
JOIN states ON student.state_id = states.id只是为了得到州的名字。
或者要进行筛选:
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的情况下构建你的查询。这并不是一种常见的做法,但如果您想做一些更快的事情,并且可以确保假设值的有效性,则可以这样做。
发布于 2014-10-22 22:53:38
首先,我建议使用@GordonLinoff的答案。他对ENUM类型的看法与我的一致。它似乎没有任何真正积极的东西去做。我将此作为单独的答案添加,因为它在DB架构中经常被忽略。
戈登的回答,以及我对它的补充评论表明,规范化是一条可行的道路。将整数键存储在大表中,并将值存储在单独的表中。每个键/值对都有不同的表。对于95%的应用程序来说,这是正确的方法。无论如何,我都会避免在PHP中存储您的值。无论何时需要添加新的键/值对,都必须编辑代码,这是应该避免的。
您说这个表主要是被读取的,所以我认为考虑对数据进行反规范化是很重要的。我仍然不建议ENUM,因为我认为数据验证/限制应该是前端的功能,而不是数据库的功能,但是您可能会发现在主表中存储实际值而不是键更有利。连接对于读取应用程序来说代价很高,因此将值直接粘贴到要从中读取的表中,并对它们进行适当的索引,将使所有内容保持快速运行。
通常,当我们处理的应用程序是事务性的(写入),但有报告(读取)的需求时,我们会优化写入并高度规范化模式,但为了满足在报告端快速读取的需求,我们会在严重非规范化的单独表中重写数据。我们尝试将尽可能多的字段打碎到一个表中。通常将键和值都存储在同一个表中。这会产生大量丑陋的数据,但读取速度要快得多。
与大多数DB模式练习一样,您必须做适合您的应用程序的事情。这通常是一个平衡相互冲突的需求和牺牲速度以求理智的问题。
https://stackoverflow.com/questions/26509801
复制相似问题