在 MySQL 5.0.45 数据库中,我想删除 2 列 UNIQUE 约束,因为它包含我要删除的列。包含在两列 UNIQUE 约束中的一列在同一个表中也是 FK 约束的 - 但是我认为这与接下来的内容无关。
以下示例表和数据是虚构的,但它们模仿了我的真实表的形式(约束、关系),当我尝试修改它们时会导致相同的问题。
在示例中,我想UNIQUE(library_id, external_id)
从书中删除约束。(因为我想删除该external_id
列。)
-- Libraries
CREATE TABLE library (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL UNIQUE
-- other columns
) ENGINE=INNODB;
-- Each book belongs to a library.
-- Each library has its own ID for the book (which we call
-- external_id). Each library should have allocated a
-- given external ID only once, but across libraries the
-- same external ID may have been allocated more than once.
CREATE TABLE book (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
library_id INTEGER NOT NULL,
CONSTRAINT book_library_id_fkey FOREIGN KEY(library_id) REFERENCES library(id),
external_id VARCHAR(20) NOT NULL,
UNIQUE(library_id, external_id)
-- other columns
) ENGINE=INNODB;
-- Made up example data
INSERT INTO library(id, name) VALUES
(1, "London"),
(2, "Cardiff"),
(3, "Dublin");
INSERT INTO book(id, name, library_id, external_id) VALUES
(1, "Programming Lisp", 1, "PL-42"),
(2, "Portable Lasers", 2, "PL-42"),
(3, "Programming Lisp", 2, "PL-43");
尝试 1:直接删除不需要的列不起作用:
> ALTER TABLE book DROP COLUMN external_id;
Error: Duplicate entry '2' for key 2
SQLState: 23000
ErrorCode: 1062
我相信这会失败,因为删除该列也会从 UNIQUE 约束(即索引)中删除该列,这会使该索引仅索引一列 - 现在这包括重复值(2 x“PL-42”)。
尝试 2:仅删除索引。
以下 SO 帖子建议如何直接删除索引:Dropping Unique constraint from MySQL table。但是,使用SHOW INDEX FROM book
列出两个具有相同值“library_id”的“Key_name”条目:
> SHOW INDEX FROM book;
+-------+------------+--------------+-------------+
| Table | Key_name | Seq_in_index | Column_name |
+-------+------------+--------------+-------------+
| book | PRIMARY | 1 | id |
| book | library_id | 1 | library_id |
| book | library_id | 2 | external_id |
+-------+------------+--------------+-------------+
[为清楚起见,省略了一些列。]
按照帖子的建议进行操作,然后失败并出现一个有点神秘的错误,但可能是由于模棱两可(它适用于非模棱两可的情况):
> DROP INDEX library_id ON book;
Error: Error on rename of '.\a6_head_dev$nemo\#sql-bd8_1' to '.\a6_head_dev$nemo\book' (errno: 150)
SQLState: HY000
ErrorCode: 1025
(当 SHOW INDEX 报告下的重复值时,如何删除 INDEX Key_name
?)
我有一个备用选项,即在没有列和唯一约束的情况下重新创建整个表external_id
,插入原始表中的所有内容,删除旧表并重命名。
但我想知道是否有更清洁的解决方案。我想知道在 MySQL(任何版本)中是否有更好的方法来做到这一点。但不幸的是,我目前被 5.0 困住了,所以我真的需要一个可以解决这个问题的解决方案。