简体   繁体   English

Mysql数据类型 - Enum或不枚举,Enum是否为空?

[英]Mysql Datatype - Enum or not to Enum, Can Enum be blank?

I have large DB (many millions of rows) and I'm trying to make the best choices for datatypes for 2 fields. 我有大型数据库(数百万行),我正在尝试为2个字段的数据类型做出最佳选择。 Most everything I have made varchar or INT. 我做的大部分都是varchar或INT。 However, 2 fields I'm wondering if Enum is the best way. 然而,2个领域我想知道Enum是否是最好的方式。

Field 1 First field is gender, My data is currently either 'Male' or 'Female' or it could be blank. 字段1第一个字段是性别,我的数据目前是“男性”或“女性”,或者可能是空白。 I initially set it up like this: 我最初设置如下:

GENDER VARCHAR(6) NOT NULL

Is this the best way, or would it be better to set it up as: 这是最好的方式,还是最好将其设置为:

GENDER ENUM ('Male', 'Female') NOT NULL

And do I need to make it NOT NULL to allow for the blank, or do I need to add the blank, ie 我是否需要将其设为NOT NULL以允许空白,或者我是否需要添加空白,即

GENDER ENUM ('Male', 'Female', '') NOT NULL

Not to mention, I'm considering converting the entire field to just M or F. 更何况,我正在考虑将整个领域转换为M或F.

Field 2: I have pretty much the same things to consider, except for the state field, which could include 52 values (50 states, DC, plus blank). 字段2:除了状态字段之外,我还有很多相同的事情需要考虑,其中包括52个值(50个状态,DC,加上空白)。

I guess the biggest question is - Is all this Enum stuff worth it? 我想最大的问题是 - 所有这些Enum的东西都值得吗? My DB has many millions of rows, so everything is a factor, but should I just be using VARCHAR(2) for the states instead of ENUM. 我的数据库有数百万行,所以一切都是一个因素,但我应该只使用VARCHAR(2)作为状态而不是ENUM。

The rule of thumb I usually apply to such cases is NOT to use MySQL ENUMs. 我经常适用于这种情况的经验法则是不使用MySQL ENUM。 Using them creates maintenance issues, especially around adding/removing/renaming some of the values. 使用它们会产生维护问题,尤其是在添加/删除/重命名某些值时。 In InnoDB, renaming and removing an enum value is heavy on big tables. 在InnoDB中,重命名和删除枚举值在大表上很重要。 Adding a value isn't (as long as you don't add it in the middle). 不添加值(只要您不在中间添加它)。

As you probably DO want to keep this column in context, and not to allow any value out of this context, the best way IMHO is to use INT, and connect it as a foreign key to a values table (columns id, value). 由于您可能希望将此列保留在上下文中,并且不允许任何值超出此上下文,因此IMHO使用INT的最佳方式是将其作为外键连接到值表(列id,值)。

You will be able to add and rename values in this table easily, and before you remove a value the FK will enforce handling any existing records in the main table which have this value. 您可以轻松地在此表中添加和重命名值,在删除值之前,FK将强制处理主表中具有此值的任何现有记录。

To read the data easily, all you need is a simple JOIN. 要轻松读取数据,您只需要一个简单的JOIN即可。

Note: since genders are pretty final, you may want to leave it as VARCHAR(1) or use an ENUM like Johan suggests, but who knows? 注意:既然性别是最终的,你可能想把它保留为VARCHAR(1)或使用像Johan建议的ENUM,但谁知道呢? You may want to support transgenders and androgyny in the future. 您可能希望将来支持跨性别者和双性化。 Not kidding. 不开玩笑。

If you want to have a value for no value entered , use null that's what null is designed for! 如果你想要一个no value entered值的no value entered ,请使用null ,这就是为null设计的!

If you want to specify something in between male and female (a few unfortunate people have this condition), use 如果你想在男性和女性之间指定一些东西(一些不幸的人有这种情况),请使用

ENUM('male','female','neither') NULL;

Note that an enum does not store the literal text value in the column. 需要注意的是一个枚举存储在列中的文字文本值。
male is stored as 1, female as 2 and neither as 3 etc. male存储为1, female存储为2, neither为3等。
This means that it is much more efficient than varchar. 这意味着它比varchar更有效。

If you are struggling with null in your selects, note that you can use the ifnull or coalesce functions to replace the null with something more usefull. 如果您在选择中遇到null ,请注意您可以使用ifnullcoalesce函数将null替换为更有用的null

SELECT IFNULL(gender,'unknown') as gender FROM people;
-- or the identical statement
SELECT COALESCE(gender,'unknown') as gender FROM people;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM