Mysql数据类型-枚举或不枚举,枚举可以为空吗?

Mysql数据类型-枚举或不枚举,枚举可以为空吗?,mysql,database,database-schema,Mysql,Database,Database Schema,我有很大的数据库(数百万行),我正试图为两个字段的数据类型做出最佳选择。我制作的大部分内容都是varchar或INT。但是,我想知道Enum是否是最好的方法 字段1 第一个字段是性别,我的数据当前为“男性”或“女性”,也可能是 空白。我最初是这样设置的: GENDER VARCHAR(6) NOT NULL 这是最好的方法,还是将其设置为: GENDER ENUM ('Male', 'Female') NOT NULL 和,我需要使它不是NULL允许空白,或者我需要添加空白,即 GENDER

我有很大的数据库(数百万行),我正试图为两个字段的数据类型做出最佳选择。我制作的大部分内容都是varchar或INT。但是,我想知道Enum是否是最好的方法

字段1 第一个字段是性别,我的数据当前为“男性”或“女性”,也可能是 空白。我最初是这样设置的:

GENDER VARCHAR(6) NOT NULL
这是最好的方法,还是将其设置为:

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

和,我需要使它不是NULL允许空白,或者我需要添加空白,即

GENDER ENUM ('Male', 'Female', '') NOT NULL
更不用说,我正在考虑将整个字段转换为m或F

字段2: 除了状态字段之外,我还有很多相同的事情要考虑,它可以包括52个值(50个状态,DC,加上空白)。
我想最大的问题是——所有这些枚举值吗?我的数据库有数百万行,因此所有内容都是一个因素,但我是否应该对状态使用VARCHAR(2)而不是ENUM。

我通常对此类情况应用的经验法则是不使用MySQL ENUM。使用它们会产生维护问题,尤其是在添加/删除/重命名某些值时。在InnoDB中,重命名和删除枚举值对大型表来说是一项繁重的任务。添加值并不重要(只要不在中间添加)

由于您可能确实希望将此列保留在上下文中,并且不允许任何值脱离此上下文,因此IMHO的最佳方法是使用INT,并将其作为外键连接到值表(columns id,value)

您将能够轻松地在此表中添加和重命名值,在删除值之前,FK将强制处理主表中具有此值的任何现有记录

要轻松读取数据,只需简单的连接即可


注意:由于性别是非常确定的,您可能希望将其保留为VARCHAR(1)或使用Johan建议的枚举,但谁知道呢?你可能希望在将来支持变性人和双性同体。不是开玩笑

如果您想为
输入值,请使用
null
这就是
null
的设计目的

如果您想指定介于男性和女性之间的内容(少数不幸的人有这种情况),请使用

请注意,枚举不在列中存储文本值。
男性
存储为1,
女性
存储为2,
两者都不存储为3,以此类推
这意味着它比varchar更高效

如果您在选择中遇到了
null
问题,请注意,您可以使用
ifnull
coalesce
函数来替换
null

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

+1用于正确使用NULL和相关函数示例。通常我会同意,但对于性别2,可能3绝对最大值7,我认为这太过分了。@Johan:7对于我的外星空间战斗游戏来说是一个非常小的数字。除开玩笑外,
CHAR(1)
是一个有效的方法。它甚至允许您向引用表中添加一个外键(包含2、3、7行内容),并且当您需要添加新的性别(或
'Unknown'
值)时,您不必处理
ENUM
。我关心的一件事是将来导入CSV文件。我不想遇到空白字段可能会中断导入的问题。@ypercube,快到睡觉时间了,我该怎么把那张照片从脑海中抹去呢?
SELECT IFNULL(gender,'unknown') as gender FROM people;
-- or the identical statement
SELECT COALESCE(gender,'unknown') as gender FROM people;