【问题标题】:MySQL - Prevent duplicate records in table via index?MySQL - 通过索引防止表中的重复记录?
【发布时间】:2009-11-18 18:03:12
【问题描述】:

使用 MySQL 5

我有一张这样的桌子:

date (varchar)
door (varchar)
shift (varchar)
route (varchar)
trailer (varchar)
+ other fields

此表包含用户生成的内容(从另一个“主”表复制)并防止用户创建超过 1 倍的相同数据,该表具有基于上述指定字段创建的唯一索引。

问题是“重复预防”索引不起作用。
用户仍然可以添加重复记录而不会报告错误。

这个问题是因为我不了解索引的工作原理吗?

或者

是否可能与主键字段(autoincrementing int)冲突?

CREATE TABLE 如下所示:

CREATE TABLE /*!32312 IF NOT EXISTS*/ "tableA" (
"Date" varchar(12) default NULL,
"door" varchar(12) default NULL,
"Shift" varchar(45) default NULL,
"route" varchar(20) default NULL,
"trailer" varchar(45) default NULL,
"fieldA" varchar(45) default NULL,
"fieldB" varchar(45) default NULL,
"fieldC" varchar(45) default NULL,
"id" int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY  ("id"),
UNIQUE KEY "duplicate_preventer" ("Date","door","Shift","route","trailer"),

重复的一行是:

date       door  shift      route    trailer

10/4/2009  W17   1st Shift  TEST-01  NULL
10/4/2009  W17   1st Shift  TEST-01  NULL

【问题讨论】:

  • 请显示 CREATE TABLE 语句。
  • 您能发布几行您认为重复的行吗?
  • 您使用的是什么数据库引擎,例如 InnoDB 或 MyISAM?
  • InnoDB 是数据库引擎。重复的行将是:日期、门、班次、路线、拖车 10/4/2009、W17、1st Shift、TEST-01、NULL 10/4/2009、W17、1st Shift、TEST-01、NULL

标签: sql mysql indexing


【解决方案1】:

用户仍然可以添加重复记录而不会报告错误。

“重复记录”是什么意思?

根据排序规则、大小写、重音等可能很重要,'test''TEST' 不会被视为重复。

能否请您发布SHOW CREATE TABLE mytable的结果?

另外,请您运行此查询:

SELECT  date, door, shift, route, trailer
FROM    mytable
GROUP BY
        date, door, shift, route, trailer
HAVING  COUNT(*) > 1

如果返回行,则问题出在索引上;如果不是,则问题在于您对“重复”的定义。

更新:

您的列允许NULLs。

UNIQUE 索引的角度来看,MySQL 中的NULL 值不被视为重复:

CREATE TABLE testtable (door VARCHAR(20), shift VARCHAR(15), UNIQUE KEY (door, shift));

INSERT
INTO    testtable
VALUES
('door', NULL),
('door', NULL);

SELECT  door, shift
FROM    testtable
GROUP BY
        door, shift
HAVING  COUNT(*) > 1;

来自documentation

UNIQUE 索引创建一个约束,使得索引中的所有值都必须是不同的。如果您尝试使用与现有行匹配的键值添加新行,则会发生错误。此约束不适用于 NULL 值,BDB 存储引擎除外。对于其他引擎,UNIQUE 索引允许包含NULL 的列的多个NULL 值。如果您为 UNIQUE 索引中的列指定前缀值,则列值在前缀中必须是唯一的。

【讨论】:

  • 它确实返回了重复的行 - 所以问题是索引。
  • 另外,对我来说,重复记录的所有字段(在索引中)都完全相同。
  • 能否请您发布SHOW CREATE TABLE mytable 的输出?问题肯定出在索引上,只是没有创建 UNIQUE 或根本没有创建。
  • 我发布了创建表的语法。
  • 问题出在NULLs
【解决方案2】:

您确定您使用的是唯一索引而不是普通索引吗?

create unique index uix on my_table (date, door, shift, route, trailer);

此外,这种索引只能确保字段组合是唯一的,例如,如果字段门在每一行上都不同,则可以有多个重复的日期。差异可能是难以发现的,例如值末尾的空格或小写/大写差异。

更新:您的唯一索引似乎是有序的。问题出在其他地方。

【讨论】:

  • 我通常通过 MySQL Administrator 或在本例中为 HeidiSQL 创建索引。我为索引设置了所需的列,然后选择“唯一”选项。
【解决方案3】:

我认为您希望在不想重复的字段上创建唯一约束。这将反过来创建一个唯一索引。

像这样:

更改表 YourTable ADD CONSTRAINT uc_yourconstraintname UNIQUE(日期、门、班次、路线、拖车)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 2013-11-11
    相关资源
    最近更新 更多