如何在MySQL中的ENUM类型列中添加更多成员?

Zai*_*aid 144 mysql enums alter-table

MySQL参考手册没有提供有关如何执行此操作的明确示例.

我有一个ENUM类型的国家/地区列,我需要添加更多国家/地区.实现此目的的MySQL语法是什么?

这是我的尝试:

ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia');
Run Code Online (Sandbox Code Playgroud)

我得到的错误是: ERROR 1265 (01000): Data truncated for column 'country' at row 1.

country列是上述语句中的ENUM类型列.

SHOW CREATE TABLE OUTPUT:

mysql> SHOW CREATE TABLE carmake;
+---------+---------------------------------------------------------------------+
| Table   | Create Table
+---------+---------------------------------------------------------------------+
| carmake | CREATE TABLE `carmake` (
`carmake_id` tinyint(4) NOT NULL AUTO_INCREMENT,
`name` tinytext,
`country` enum('Japan','USA','England','Australia','Germany','France','Italy','Spain','Czech Republic','China','South Korea','India') DEFAULT NULL,
PRIMARY KEY (`carmake_id`),
KEY `name` (`name`(3))
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=latin1 |
+---------+---------------------------------------------------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

SELECT DISTINCT country from carmake OUTPUT:

+----------------+
| country        |
+----------------+
| Italy          |
| Germany        |
| England        |
| USA            |
| France         |
| South Korea    |
| NULL           |
| Australia      |
| Spain          |
| Czech Republic |
+----------------+
Run Code Online (Sandbox Code Playgroud)

小智 111

ALTER TABLE
    `table_name`
MODIFY COLUMN
    `column_name2` enum(
        'existing_value1',
        'existing_value2',
        'new_value1',
        'new_value2'
    )
NOT NULL AFTER `column_name1`;
Run Code Online (Sandbox Code Playgroud)

  • 大多数ALTER TABLE命令将完全重写整个表.mysql是否足够聪明,不能用enum做到这一点? (6认同)
  • 一个明确而快速的可用答案谢谢. (2认同)
  • enum 只是一个花哨的整数,用字符串表示。将项目添加到末尾很好,因为您只需添加有意义的旧值。但是更改顺序/删除枚举会使这些数字未定义。(例如1=>意大利,2=>德国),那么扩展将是(1=>意大利,2=>德国,3=>瑞典)。 (2认同)
  • @约翰取决于。对于 MariaDB,从 10.3.7 开始,可以在枚举末尾添加新值:https://mariadb.com/kb/en/library/innodb-online-ddl-operations-with-algorithminstant/#添加新的枚举选项 (2认同)

Asa*_*aph 96

你的代码适合我.这是我的测试用例:

mysql> CREATE TABLE carmake (country ENUM('Canada', 'United States'));
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW CREATE TABLE carmake;
+---------+-------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                            |
+---------+-------------------------------------------------------------------------------------------------------------------------+
| carmake | CREATE TABLE `carmake` (
  `country` enum('Canada','United States') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+---------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia');
Query OK, 0 rows affected (0.53 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE carmake;
+---------+--------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                       |
+---------+--------------------------------------------------------------------------------------------------------------------+
| carmake | CREATE TABLE `carmake` (
  `country` enum('Sweden','Malaysia') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+---------+--------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

你看到什么错误?

FWIW这也可行:

ALTER TABLE carmake MODIFY COLUMN country ENUM('Sweden','Malaysia');
Run Code Online (Sandbox Code Playgroud)

我实际上会推荐一个国家表而不是枚举列.你可能有数百个国家会产生一个相当庞大和笨拙的枚举.

编辑:现在我可以看到您的错误消息:

ERROR 1265 (01000): Data truncated for column 'country' at row 1.
Run Code Online (Sandbox Code Playgroud)

我怀疑您的国家/地区列中有一些值未显示在您的列中ENUM.以下命令的输出是什么?

SELECT DISTINCT country FROM carmake;
Run Code Online (Sandbox Code Playgroud)

另一个编辑:以下命令的输出是什么?

SHOW VARIABLES LIKE 'sql_mode';
Run Code Online (Sandbox Code Playgroud)

难道STRICT_TRANS_TABLES还是STRICT_ALL_TABLES?这可能会导致错误,而不是MySQL在这种情况下会给你的通常警告.

再来一次编辑:好的,我现在看到你的表中肯定有值不属于新的值ENUM.新ENUM定义仅允许'Sweden''Malaysia'.该表具有'USA','India'和其他几个人.

最后编辑(MAYBE):我想你正在尝试这样做:

ALTER TABLE carmake CHANGE country country ENUM('Italy', 'Germany', 'England', 'USA', 'France', 'South Korea', 'Australia', 'Spain', 'Czech Republic', 'Sweden', 'Malaysia') DEFAULT NULL;
Run Code Online (Sandbox Code Playgroud)

  • -1因为这里的实际解决方案不够清晰.有太多的谈话和很多"尝试这个,哦,试试这个." 初始响应甚至没有回答OP的实际问题 - 直到后来你才意识到问题是什么,然后你进入简单的代码示例,这对于找到这个问题/答案的人来说实际上并不意味着什么晚些时候.编辑的上下文是/是暂时的,不再是显而易见的. (3认同)
  • @Zaid 我认为您的表中确实有更新的 ENUM 定义中没有的值。您的新定义只允许瑞典和马来西亚。您的表中有美国、印度、德国……您的新 ENUM 中不允许使用这些值。如果您要*添加*瑞典和马来西亚,同时保留 ENUM 的原始成员,则需要重新列出*所有*原始 ENUM 值以及 ALTER 语句中的 2 个新值。 (2认同)
  • @Zaid你很受欢迎.如果你像我之前建议的那样使用带有外键而不是ENUM的国家/地区表,那么您将能够简单地为新国家/地区添加行.顺便说一句:如果您发现我的建议有帮助,请标记我的答案正确:) (2认同)

Zai*_*aid 73

我和Asaph 的讨论可能不清楚,因为我们来回走了很多.

我认为我可能会澄清我们的讨论结果,以便将来可能面临类似情况的其他人受益于:

ENUM - 类型的列是非常难以操纵的野兽.我想在我的ENUM中将两个国家(马来西亚和瑞典)添加到现有的国家/地区.

似乎MySQL 5.1(我正在运行的)只能通过重新定义现有的集合以及我想要的内容来更新ENUM:

这不起作用:

ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia') DEFAULT NULL;
Run Code Online (Sandbox Code Playgroud)

其原因是,MySQL的声明与另一种含条目替换现有ENUM 'Malaysia''Sweden'唯一的.MySQL引发了一个错误,因为该carmake表已经具有类似的值'England','USA'并且不属于新ENUM定义的一部分.

令人惊讶的是,以下内容也不起作用:

ALTER TABLE carmake CHANGE country country ENUM('Australia','England','USA'...'Sweden','Malaysia') DEFAULT NULL;
Run Code Online (Sandbox Code Playgroud)

事实证明,在ENUM向其添加新成员时,甚至需要保留现有元素的顺序.因此,如果我的现有ENUM看起来像ENUM('England','USA'),那么我的新ENUM必须被定义为ENUM('England','USA','Sweden','Malaysia')而不是ENUM('USA','England','Sweden','Malaysia').只有在现有表中存在使用'USA''England'值的记录时,此问题才会显现.

底线:

ENUM当您不希望您的成员集在定义后更改时才使用s.否则,查找表更容易更新和修改.

  • 我不确定我同意这个底线.相信我,我根本不喜欢ENUM,但我没有看到添加到可能的ENUM中的危险.ENUM的核心是0 - >选项1,1,>选项2等的映射.添加到那里不应该引起问题. (6认同)
  • @JoshStrange这不是一个危险,当您的ENUM的顺序很重要时(例如,用于订购时),这可能会带来巨大的不便. (2认同)
  • 我认为在底线中说这一点也很重要,即这仅对旧版本的 MySQL 有效,因为据我了解,对于较新的版本没有问题。 (2认同)

小智 24

在 MYSQL 服务器版本:5.0.27 中,我尝试了此操作,它对我来说运行良好,请检查您的版本

ALTER TABLE carmake
     MODIFY `country` ENUM('Japan', 'USA', 'England', 'Australia', 'Germany', 'France', 'Italy', 'Spain', 'Czech Republic', 'China', 'South Korea', 'India', 'Sweden', 'Malaysia');
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这没有得到更多的支持。这很简单,而且对我有用。 (2认同)