假设我有这个表,在mysql workbench和Innodb引擎中都有两列作为主键:
+--------+---------+
| grp | name |
+--------+---------+
| fish | lax |
| mammal | dog |
| mammal | bat |
| mammal | whale |
| bird | bat |
| bird | ostrich |
+--------+---------+
如何添加列,使用grp列表现如下:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 2 | dog |
| mammal | 2 | cat |
| mammal | 2 | whale |
| bird | 3 | penguin |
| bird | 3 | ostrich |
+--------+----+---------+
请注意,我想要更改的实际表格要大得多。另请注意,这不是使用MyISAM进行自动递增的情况,而不是此处要求的内容(但答案可能会有所帮助):How to auto increment on different foreign keys?
答案 0 :(得分:0)
CREATE TABLE Groups (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
grp VARCHAR...
PRIMARY KEY(id),
UNIQUE(grp)
) ENGINE=InnoDB
SELECT DISTINCT grp FROM YourTable;
这应该为您提供grp
和id
之间的映射。
此时,您不应该生成包含3列(grp + id + name)的表格,而是使用上面的Groups
作为"规范化",您似乎是这样做。然后做
CREATE TABLE New LIKE YourTable;
ALTER TABLE New
ADD COLUMN id INT UNSIGNED NOT NULL,
DROP COLUMN grp;
# Note: if you have an index on grp, something else may need to be done.
INSERT INTO New
SELECT g.id, y.name
FROM Groups g
JOIN YourTable y ON y.grp = g.grp;
# At this point, verify that `New` has what you want. Then switch over:
RENAME TABLE YourTable TO Old, New TO YourTable;
DROP TABLE Old;
编辑我选择创建一个新表而不是更新现有表 - 因为它(我认为)会快得多。使用UPDATE
时,需要锁定所有行。使用INSERT..SELECT
,只需创建它们。