如何解决如何使一列的约束值与另一列的约束值相同?
TABLE 1 (photos)
photo_id | student_id | main_photo
----------------------------------
1 | 1 | 0
2 | 1 | 1
3 | 2 | 1
4 | 1 | 0
我需要确保对于相同的student_id,只有一张主照片。因此,1
的值只能是一个,并且不能为两个或多个(对于同一个student_id),但是0
的值可以是多个(一个以上)。
MysqL版本:5.7
解决方法
您真正想要的是一个经过过滤的唯一索引。 MySQL,MySQL不允许这样做。
相反,您可以对生成的列使用技巧:
alter table photos add main_photo_null int generated always as
(nullif(main_photo,0));
然后您可以在唯一约束中使用它:
create unique index unq_photos_main on photos(student_id,main_photo_null);
MySQL在唯一索引/约束中为NULL
允许多个值,因此当main_photo
值为0
时,不强制执行唯一性。
Here是db 小提琴。
,在最新的MySQL版本中,可以在唯一索引中使用case
表达式:
create unique index idx_photos_uniq
on photos((case when main_photo then student_id end));
这在逻辑上为student_id
的行上强制执行main_photo
的唯一性(实际上假设这是一个布尔列-否则您可能想要when main_photo = 1
)。
create table photos (
photo_id int auto_increment primary key,student_id int,main_photo int
);
create unique index idx_photos_uniq
on photos((case when main_photo then student_id end));
insert into photos (student_id,main_photo) values (1,1);
insert into photos (student_id,0);
insert into photos (student_id,main_photo) values (2,0);
-- ok
insert into photos (student_id,1);
-- error: Duplicate entry '1' for key 'photos.idx_photos_uniq'
,
使用唯一的注解更改atbe,您将在下面看到结果
CREATE TABLE photos ( `photo_id` INTEGER,`student_id` INTEGER,`main_photo` INTEGER ); ALTER TABLE photos ADD CONSTRAINT UC_student_id UNIQUE (student_id);
INSERT INTO photos (`photo_id`,`student_id`,`main_photo`) VALUES ('1','1','0')
INSERT INTO photos (`photo_id`,`main_photo`) VALUES ('2','1')
INSERT INTO photos (`photo_id`,`main_photo`) VALUES ('3','2','1')
SELECT * FROM photos
photo_id | student_id | main_photo -------: | ---------: | ---------: 1 | 1 | 0 3 | 2 | 1
db 提琴here
出于您的目的,您可以使用INSERT TRIGGER之前,它可以检查main_photo = 1
CREATE TABLE photos ( `photo_id` INTEGER,`main_photo` INTEGER );
#DELIMITER $$ CREATE TRIGGER before_photos_insert BEFORE INSERT ON photos FOR EACH ROW BEGIN IF EXISTS(SELECT 1 FROM photos WHERE `main_photo` = 1 AND `student_id` = NEW.`student_id`) THEN SIGNAL sqlstate '45002' set message_text = 'mainphoto already exsits'; END IF; END ; #$$ #DELIMITER ;
INSERT INTO photos (`photo_id`,`main_photo`) VALUES ('4','1')
mainphoto already exsits
SELECT * FROM photos
photo_id | student_id | main_photo -------: | ---------: | ---------: 1 | 1 | 0 2 | 1 | 1 3 | 2 | 1
db 提琴here
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。