Ifølge dokumentationen ,
Så fjerner du not null -constraint fra Status og tilføjelse af et unikt indeks på (ContactId,PhoneId,Status) vil fungere som du vil have det til, hvis du bruger null i stedet for 0 for inaktiv optegnelser.
Hvis du ikke vil eller kan bruge null for din Status kolonne, vil du sikre dig både Status=0 og Status=null opføre sig identisk, eller f.eks. ønsker at behandle Status=2 som aktiv (og håndhæver unikhed), kan du også tilføje en dummy-kolonne, der vil blive beregnet ud fra Status .
Hvis du bruger MySQL 5.7+, kan du gøre dette med en genereret kolonne:
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
Ellers kan du bruge en normal kolonne og bruge triggere til at beregne værdien af kolonnen, f.eks.:
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);
Du kan selvfølgelig skifte formlen til f.eks. if(new.Status <> 0, new.Status, null); hvis du vil tillade forskellige værdier af Status også.