Theo tài liệu ,
Vì vậy, loại bỏ not null
-biểu tượng từ Status
và thêm một chỉ mục duy nhất trên (ContactId,PhoneId,Status)
sẽ hoạt động như bạn muốn, nếu bạn sử dụng null
thay vì 0
vì không hoạt động hồ sơ.
Nếu bạn không muốn hoặc không thể sử dụng null
cho Status
của bạn , muốn đảm bảo cả hai Status=0
và Status=null
hành xử giống hệt nhau, hoặc ví dụ:muốn xử lý Status=2
as hoạt động (và thực thi tính duy nhất), bạn có thể thêm một cột giả sẽ được tính toán từ Status
.
Nếu bạn đang sử dụng MySQL 5.7+, bạn có thể thực hiện việc này với một cột đã tạo:
CREATE TABLE IF NOT EXISTS `ContactPhone` (
`ContactPhoneId` int(10) unsigned NOT NULL auto_increment primary key,
`ContactId` int(11) NOT NULL,
`PhoneId` smallint(5) unsigned NOT NULL,
`Status` tinyint(1) NOT NULL DEFAULT '1',
`StatusUnq` tinyint(1) as (if(Status <> 0, 1, null)) stored null,
constraint unique (ContactId, PhoneId, StatusUnq)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (1, 1, 1, 1);
insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (2, 1, 1, 1);
-- Duplicate key error
insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (3, 1, 1, 0);
insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
values (4, 1, 1, 0);
update ContactPhone set Status = 1 where ContactPhoneId = 4;
-- Duplicate key error
Nếu không, bạn có thể sử dụng cột bình thường và sử dụng trình kích hoạt để tính toán giá trị của cột, ví dụ:
create trigger trbi_contactPhoneUnique before insert on ContactPhone
for each row
set new.StatusUnq = if(new.Status <> 0, 1, null);
create trigger trbu_contactPhoneUnique before update on ContactPhone
for each row
set new.StatusUnq = if(new.Status <> 0, 1, null);
Tất nhiên, bạn có thể chuyển công thức thành v.d. if(new.Status <> 0, new.Status, null);
nếu bạn muốn cho phép các giá trị khác nhau của Status
cũng vậy.