我正在使用一个mysql数据库表,它将一个6位值存储为枚举。仅指定了20个左右的值,其余的名称类似于“type_30”。我现在正在更改列,使用alter TABLE table_name modify COLUMN column_name enum( 'text', ... );
为某些值添加描述性文本。表格并不是那么大(大约13e6行),但是alter命令已经运行了很长时间。我有点惊讶,因为看起来更改枚举类型应该只需要修改表的元数据(因此表中的行数应该是无关紧要的。)
为什么列中的行数对此类操作很重要?我有一种简单的方法可以快速更改枚举的标签吗?
答案 0 :(得分:4)
通过添加新的来更改ENUM或SET列的定义 枚举或将成员设置为有效成员列表的末尾 值,只要数据类型的存储端不改变。 例如,将成员添加到具有8个成员的SET列 将每个值所需的存储空间从1个字节更改为2个字节;这个 需要一份表副本。在列表中间添加成员 导致重新编号现有成员,这需要一个表格副本。
枚举存储为整数。例如,如果你的枚举是('是','否','是'将是1而'否'将是2。
在中间插入新项目需要重新编号,因此MySQL将创建一个新表并复制行以更改数据。这不仅仅是对元数据的改变。
没有快速更改现有标签的方法,因为它会影响数据。但是,如果只将值添加到枚举的末尾,则只需要更改元数据。
答案 1 :(得分:1)
没有简单的方法可以快速更改枚举列的标签。像你一样运行MODIFY COLUMN not 更新标签,它实际上是尝试重新映射所有现有数据以适应更新的枚举值。
例如,如果您的列之前是ENUM('blue','red','yellow'),那么您将拥有以下索引值:
1 = blue
2 = red
3 = yellow
如果您运行alter TABLE table_name modify COLUMN column_name enum( 'red','yellow','blue' );
,它将更新索引值,如下所示:
1 = red
2 = yellow
3 = blue
这是你想要的。但它也会返回并更新表的所有现有行以重新映射索引值:
1 -> 3
2 -> 1
3 -> 2
你不想要的。
如果您只是想在不修改现有行数据的情况下更新标签,则需要修改FRM文件。以下是如何执行此操作的说明: