Zab*_*bba 3 mysql unique-constraint
我有一个存储在表中的代码列表,有些代码应该是唯一的,其他代码可以重复。这些代码应该是唯一范围到另一个字段product_id.
假设每个代码11只允许一次product_id,并且允许其他代码重复,该表将如下所示:
product_id code
1 11 # Needs to be unique for product_id 1
1 222
1 222
1 333
2 11 # Needs to be unique for product_id 2
2 222
2 444
Run Code Online (Sandbox Code Playgroud)
使用 MySQL,我利用了一个事实,即您可以在唯一索引中拥有多个 NULL 值,因此通过添加一个“决胜局”(?) 字段ucode,我能够一起破解一个解决方案:
product_id code ucode
1 11 1 # Code 11 needed to be unique, so 1 for ucode
1 222 NULL # Code 222 can be repeated, so NULL for ucode
1 222 NULL
1 333 NULL
2 11 1
2 222 NULL
2 444 NULL
Run Code Online (Sandbox Code Playgroud)
然后在 [product_id, code, ucode] 上建立唯一索引。对于唯一代码,该ucode字段设置为1,否则设置为NULL。
这有效,但感觉非常笨拙。有没有更好的方法可以做到这一点?
(我正在使用 MySQL)
在MySQL 5.7和MariaDB 5.2+版本中,您可以使用(生成的)VIRTUAL列来完成此操作。您定义ucode为虚拟列,然后添加UNIQUE约束:
CREATE TABLE codes
( product_id INT NOT NULL,
code INT NOT NULL,
ucode BIT AS (CASE WHEN code = 11 THEN b'1' ELSE NULL END)
VIRTUAL,
-- PERSISTENT, -- for persistent storage of the value in MariaDB
-- STORED, -- for persistent storage of the value in MySQL
CONSTRAINT code_11_product_id_unique
UNIQUE (ucode, product_id)
) ;
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)insert into codes (product_id, code) values (1, 11), (1, 222), (1, 222), (1, 333), (2, 11), (2, 222), (2, 222);?
Run Code Online (Sandbox Code Playgroud)select * from codes;product_id | 代码 | 代码 ---------: | ---: | :---- 1 | 11 | 1 1 | 第222话 空 1 | 第222话 空 1 | 第333话 空值 2 | 11 | 1 2 | 第222话 空 2 | 第222话 空值
Run Code Online (Sandbox Code Playgroud)insert into codes -- should fail (product_id, code) values (2, 11) ;密钥“code_11_product_id_unique”的重复条目“\x01-2”
Run Code Online (Sandbox Code Playgroud)select * from codes;product_id | 代码 | 代码 ---------: | ---: | :---- 1 | 11 | 1 1 | 第222话 空 1 | 第222话 空 1 | 第333话 空值 2 | 11 | 1 2 | 第222话 空 2 | 第222话 空值
| 归档时间: |
|
| 查看次数: |
1988 次 |
| 最近记录: |