MySQL降级复合主键更具限制性

时间:2016-07-19 17:33:08

标签: mysql database primary-key database-migration composite-primary-key

我已经使用下表来跟踪正在观看支持票的用户

CREATE TABLE IF NOT EXISTS crm_ticketwatcher (
  ticketid int(10) unsigned NOT NULL DEFAULT '0',
  employeeid int(10) unsigned NOT NULL DEFAULT '0',
  contactid int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (ticketid,employeeid,contactid)
) ENGINE=MyISAM;

我想要一个降级脚本,从主键中删除contactid。

表格内容看起来有点像这样

ticketid|employeeid|contactid
--------|----------|---------
5       |5         |0
5       |8         |0
5       |0         |2
5       |0         |3

当我运行我的(不成功的)降级脚本时,

ALTER TABLE crm_ticketwatcher DROP PRIMARY KEY, ADD PRIMARY KEY (ticketid, employeeid);

我收到以下错误:

ERROR 1062 (23000) at line 1: Duplicate entry '306-0' for key 'PRIMARY'

因为现在有2行主键设置(5,0)

从表中删除其他行的最佳方法是什么,保存最后一行?

我们在MySQL 5.7.13上,所以IGNORE关键字不是一个选项。

感谢。

1 个答案:

答案 0 :(得分:0)

正如ALTER TABLE Syntax所述:

  

IGNORE是标准SQL的MySQL扩展。如果新表中的唯一键上存在重复项,或者启用严格模式时出现警告,它将控制ALTER TABLE的工作方式。如果未指定IGNORE,则复制将中止并在发生重复键错误时回滚。如果指定了IGNORE,则只对一行使用唯一键上具有重复项的行。其他冲突的行将被删除。不正确的值将被截断为最接近的匹配可接受值。

因此,您可以这样做:

ALTER IGNORE TABLE crm_ticketwatcher
  DROP PRIMARY KEY,
  ADD PRIMARY KEY (ticketid, employeeid);

但请注意,保留哪些“重复”行将是不确定的。

如果您想要更确定的结果,或者正在使用MySQL v5.7.4及更高版本(已从中移除IGNORE),您可以先使用多表{{1}执行自联接语法:

DELETE