ドキュメント によると 、
したがって、not null
を削除します -Status
からの制約 (ContactId,PhoneId,Status)
に一意のインデックスを追加します null
を使用すると、希望どおりに機能します 0
の代わりに 非アクティブの場合 記録。
null
を使用したくないまたは使用できない場合 Status
列、両方のStatus=0
を確認する必要があります およびStatus=null
同じように動作する、または例: Status=2
を扱いたい アクティブとして (そして一意性を強制する)また、Status
から計算されるダミー列を追加することもできます 。
MySQL 5.7以降を使用している場合は、生成された列を使用してこれを行うことができます:
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
それ以外の場合は、通常の列を使用し、トリガーを使用して列の値を計算できます(例:
)。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);
もちろん、数式を次のように切り替えることもできます。 if(new.Status <> 0, new.Status, null);
Status
の異なる値を許可する場合 それも。