为现有外键添加唯一

时间:2016-09-06 19:43:39

标签: mysql innodb

我有这张桌子

CREATE TABLE IF NOT EXISTS `transaction` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `amount` bigint(20) NOT NULL,
  `req_id` int(11) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `transactions_873a2484` (`req_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=914 ;

我想将此forign键transactions_873a2484更改为unque forign键 基本上我想把它改成

  UNIQUE KEY `transactions_req_id_de2b5683_uniq` (`req_id`),

我已经在我的桌子上有很多数据,否则我会重新制作这张桌子....无论如何要做到这一点而不伤害数据?

2 个答案:

答案 0 :(得分:1)

我会随着时间的推移改进这一点。 MySQL会尊重你的意愿,甚至允许你在你走的时候自己开枪:

create table t9
(
    id int auto_increment primary key,
    thing varchar(20) not null,
    key(thing),
    unique key (thing),
    unique key `yet_another` (thing)
);
-- warning 1831 dupe index
show create table t9;
CREATE TABLE `t9` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `thing` varchar(20) NOT NULL,
   PRIMARY KEY (`id`),
   UNIQUE KEY `thing_2` (`thing`),
   UNIQUE KEY `yet_another` (`thing`),
   KEY `thing` (`thing`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

所以看看你必须随身携带的所有行李(阅读:缓慢额外的不必要索引)。

因此,如果您希望它尽可能精简,正如我在评论中所提到的那样,首先通过在子表中删除FK来解除事物,首先是引用。请参阅This Answer

然后删除当前的非唯一父键:

DROP INDEX index_name ON tbl_name;

然后在父级中添加唯一键。这是新的引用

CREATE UNIQUE INDEX idxName ON tbl_name (colName);

然后在孩子中添加FK(引用

CREATE INDEX idxName ON child_tbl_name (colName);

您可以按show create table theTableNameSHOW INDEX获取密钥名称。使用新名称,这不重要。

如:

mysql> show index from t9;
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t9    |          0 | PRIMARY     |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| t9    |          0 | thing_2     |            1 | thing       | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| t9    |          0 | yet_another |            1 | thing       | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| t9    |          1 | thing       |            1 | thing       | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

答案 1 :(得分:0)

ALTER TABLE `transaction`
    DROP INDEX `transactions_873a2484`,
    ADD UNIQUE(req_id);

您无法将非唯一身份转换为UNIQUE,但上述内容应该相同。数据将不会受到伤害。