MySQL UNIQUE CONSTRAINT在CREATE TABLE中失败,后续INSERT

时间:2016-07-15 15:52:14

标签: mysql

使用phpMyAdmin和MySQL v5.5.49考虑:

CREATE TABLE op_sys (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    version VARCHAR(255) NOT NULL,
    -- UNIQUE KEY name_version (name, version)
    -- CONSTRAINT name_version UNIQUE (name, version)
    -- UNIQUE(name, version)
    -- CONSTRAINT UNIQUE(name, version)
)ENGINE=InnoDB;

我已经尝试了所有四个注释掉的尝试,只是为了“名称”和“版本”而停止INSERT INTO sys_op重复值。处理完所有四个都没有错误。

插入:

INSERT INTO op_sys(name, version)
VALUES ('ANDROID','ANDROID');

执行“成功”。 ANDROID ANDROID现在是一排。我哪里出错或者我不知道哪一步?我已经检查了MySQL手册和这里的几个不同的帖子,似乎说我正确地做了...谢谢。

2 个答案:

答案 0 :(得分:2)

您似乎误解了UNIQUE KEY的含义:

  

UNIQUE索引创建一个约束,以便索引中的所有值   必须是截然不同的如果您尝试使用a添加新行,则会发生错误   与现有行匹配的键值。对于所有引擎,都是独一无二的   index允许包含NULL的列的多个NULL值。

如果您的表格有UNIQUE(name, version),那么您可以执行以下操作:

INSERT INTO op_sys(name, version) VALUES ('ANDROID','ANDROID');

但是,下次你这样做时,它会失败,因为该表已经拥有一个记录,其中包含与要插入的记录相同的一对(名称,版本)。

要防止插入具有name和版本`相同值的记录,您可以使用trigger

CREATE TRIGGER different_values BEFORE INSERT ON op_sys
FOR EACH ROW BEGIN
 DECLARE identical_values CONDITION FOR SQLSTATE '45000';
 IF NEW.name = NEW.version THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Identical values for name and version';
 END IF;
END;

它将在表INSERT上的每个sys_op之前运行,如果nameversion字段包含相同的值,则会生成错误并且插入将失败

返回的错误如下所示:

ERROR 1644 (45000): Identical values for name and version

文档:
- CREATE INDEX
- CREATE TRIGGER
- SIGNAL

答案 1 :(得分:2)

多列唯一索引会阻止您为记录之间的这两个字段设置相同的2个值。这意味着,您不能拥有2条记录,其中名称和版本为“ANDROID”,“ANDROID”。但是,唯一索引不会阻止这些字段在单行中具有相同的值。

您必须在应用程序级别实现此控件,检查2个字段值是否相同,如果是,则不要插入。

在数据库层中,您可以在插入触发器之前使用ad并检查其中的2个字段的值,并使用signal命令引发自定义错误消息。

但我有这样的de ja vu感觉。好像你以前问过这个问题,你不能在php中做一个if()...