【问题标题】:How to have a concatenation of string columns as unique constraint in MySQL如何在 MySQL 中将字符串列连接为唯一约束
【发布时间】:2018-11-19 18:27:37
【问题描述】:

我有一张表说employee employee 表有几个字段,例如

`salary`
`name`
`age`
`designation`

其中只有designation 可以为空。我不能将其设为 NOT NULL,因为现有代码正在使用它。

是否可以为上述所有列创建组合唯一约束?

当我尝试创建新的唯一约束时。

ALTER TABLE `employee` ADD CONSTRAINT `employee_constraint` 
UNIQUE key (`salary`,`name`, `age`, `designation`);

它成功创建了约束,但是当我尝试插入这些记录的重复组合时,它插入成功。有没有更好的方法来创建约束并丢弃这些列的重复组合?

【问题讨论】:

  • 它插入完全相同的组合说 (1000, 'xyz', 10, NULL) 两次
  • @baao 这仅显示正在发生的事情,但没有任何解决方法
  • 对,改成相关,撤回投票@lad2025
  • 非常感谢您回答这个问题。但这是针对 MySQL 5.7 版的。但是我们可以为 5.6 版做到这一点吗?如果没有,还能做什么?

标签: mysql sql database unique-key


【解决方案1】:

通常 MySQL 允许在 UNIQUE 约束中使用多个 NULL。更多信息:Does MySQL ignore null values on unique constraints?

您可以使用生成的列来只允许一个NULL 值:

CREATE TABLE employee(salary INT, name VARCHAR(100)
                     ,age INT, designation VARCHAR(100)
                ,designation_virtual VARCHAR(100) AS (COALESCE(designation, '^'))
);

ALTER TABLE employee ADD CONSTRAINT employee_constraint 
UNIQUE key (salary,name, age, designation_virtual) ;

INSERT INTO employee(salary, name, age, designation)
VALUES(1000, 'xyz', 10, NULL);

INSERT INTO employee(salary, name, age, designation) 
VALUES(1000, 'xyz', 10, NULL);
-- Duplicate entry '1000-xyz-10-^' for key 'employee_constraint'

SELECT * FROM employee;

DBFiddle Demo


如果您使用的是 MariaDB 10.3.3,您可以将虚拟列标记为 INVISIBLE

可以给列赋予一个 INVISIBLE 属性。然后,这些列将不会在 SELECT * 语句的结果中列出,也不需要在 INSERT 语句中为其分配值,除非 INSERT 明确按名称提及它们。

ALTER TABLE employee MODIFY designation_virtual INVISIBLE;  

【讨论】:

  • 非常感谢,但是想知道这对性能有什么影响??考虑到我一次插入大约 1000 条记录并在极端情况下一次更新 5 条记录??
  • 我会说最少。但你永远不应该相信任何话。只需使用不正确的设置进行基线测试(测量完成工作的时间),然后对新的正确设置执行相同的操作(不允许重复)。
  • 看起来上面的代码不适用于 MySQL 5.6
  • @user9920500 我相信从 5.7 开始可以使用生成的列
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 2020-04-18
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
相关资源
最近更新 更多