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

标签 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);

我收到以下错误:

第 1 行的错误 1062 (23000):键“PRIMARY”的重复条目“306-0”

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

从表中删除额外行并保存最后出现的行的最佳方法是什么?

我们使用的是 MySQL 5.7.13,因此 IGNORE 关键字不是一个选项。

谢谢。

最佳答案

根据 ALTER TABLE Syntax 记录:

IGNORE is a MySQL extension to standard SQL. It controls how ALTER TABLE works if there are duplicates on unique keys in the new table or if warnings occur when strict mode is enabled. If IGNORE is not specified, the copy is aborted and rolled back if duplicate-key errors occur. If IGNORE is specified, only one row is used of rows with duplicates on a unique key. The other conflicting rows are deleted. Incorrect values are truncated to the closest matching acceptable value.

因此,您可以:

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

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

如果您想要更确定的结果,或者正在使用 MySQL v5.7.4 及更高版本(IGNORE 已从中删除),您可以首先使用多表 DELETE 语法:

DELETE c1
FROM   crm_ticketwatcher c1
  JOIN crm_ticketwatcher c2 USING (ticketid, employeeid)
WHERE  c1.contactid < c2.contactid -- or whatever logic you prefer

关于MySQL 降级复合主键以更具限制性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38465007/

相关文章:

php - 为什么 SQL 查询返回 0?实际查询是什么?

mysql - 将mysql数据库从一台电脑复制到另一台

postgresql - 我的表是否需要一个主键,它有一个 UNIQUE(复合 4 列),其中一个可以为 NULL?

django - 为什么 Django/PostgreSQL 在删除具有该主键的对象后不重用主键值?

php - 为什么 MySQL INSERT 查询会出错?错误是什么意思?

java - Spring 与 hibernate : Duplicate entry for key 'PRIMARY'

javascript - 如何在angularjs中插入和更新查询

mysql - 由于高索引基数导致查询缓慢

php - 无法在 PHP 中创建查询变量作为表名的 SQL 表

java - 如何获取jsp中选择选项中选择的数据库值?