场景:多个产品图片,一个主图片。
目前,我有2个表来管理它。一个用于存储产品图像,另一个用于存储mainProductImageIds
。在存储mainProductImageIds
列表的表格中,我在prodid
+ isMain
上有一个唯一索引,以强制执行每个产品ID一个主图像。
我的问题 与下表有关(如果我打算只使用1个表)。如何按isMain=1
强制执行1 prod
?当我尝试将isMain=1
设置为image_id=2
时,是否有任何索引设置会出错,因为image=1
已经是主要图片了?您无法在prod
+ isMain
上添加unique_key。
|image_id |prod|isMain
|---------|----|------
|0 |1 |0
|1 |1 |1
|2 |1 |0
|3 |2 |1
|4 |3 |0
|5 |3 |1
答案 0 :(得分:1)
您可以尝试使用TRIGGER
执行此操作。
CREATE TRIGGER check_unique BEFORE UPDATE ON `images`
FOR EACH ROW
SET NEW.isMain = IF(NEW.isMain = 0, 0,
CASE WHEN ( SELECT MAX(isMain) FROM images AS q WHERE q.prod = NEW.prod ) = 1
THEN NULL ELSE NEW.isMain END);
或更快(特别是如果已编入索引)
CREATE TRIGGER check_unique BEFORE UPDATE ON `images`
FOR EACH ROW
SET NEW.isMain = IF(NEW.isMain = 0, 0,
IF (EXISTS ( SELECT * FROM images AS q WHERE q.prod = NEW.prod AND q.isMain = 1), NULL, 1));
这将允许始终将isMain设置为0;如果你想把它设置为1,那么它将检查isMain为1的同一产品没有其他行。
在下面的示例中,我无法将isMain = 1
设置为prod=3
,直到我在另一张isMain=0
的图片上设置isMain = 1
。
CREATE TABLE images (
image_id integer not null primary key auto_increment,
prod integer not null, isMain integer not null );
INSERT INTO images VALUES (1, 1, 0), (2, 1, 1), (3, 2, 0), (4, 2, 1);
select * from images;
+----------+------+--------+
| image_id | prod | isMain |
+----------+------+--------+
| 1 | 1 | 0 |
| 2 | 1 | 1 |
| 3 | 2 | 0 |
| 4 | 2 | 1 |
+----------+------+--------+
CREATE TRIGGER check_unique BEFORE UPDATE
ON `images` FOR EACH ROW
SET NEW.isMain = IF(NEW.isMain = 0, 0, IF (EXISTS ( SELECT * FROM images AS q WHERE q.prod = NEW.prod AND q.isMain = 1), NULL, 1));
UPDATE images SET isMain = 1 WHERE image_id = 3;
ERROR 1048 (23000): Column 'isMain' cannot be null
UPDATE images SET isMain = 0 WHERE image_id = 4;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
UPDATE images SET isMain = 1 WHERE image_id = 3;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
您可以扩展此方法,以便始终可以将任何行的isMain设置为1 ,但该产品之前的isMain行将归零。
答案 1 :(得分:0)
我知道,答案非常简单,与MySQL索引NULL值的方式有关。 Over Here他们谈论:
对于所有引擎,UNIQUE索引允许多个NULL值 可以包含NULL的列。
所以只要我的isMain
字段允许强制执行一个值和NULL(可能是一个ENUM),我就全部设置好了。 unique_index仅在isMain设置为不同值时强制执行,而不是在设置为NULL时强制执行。
更新的表格如下所示:
|image_id |prod|isMain
|---------|----|------
|0 |1 |null
|1 |1 |1
|2 |1 |null
|3 |2 |1
|4 |3 |null
|5 |3 |1