在MySQL中使用条件值检查进行约束

时间:2017-07-02 03:16:39

标签: mysql constraints unique-constraint unique-key unique-index

我需要添加一个基于组合和值的Constrain检查

我的表结构是

CREATE TABLE IF NOT EXISTS `ContactPhone` (
  `ContactPhoneId` int(10) unsigned NOT NULL,
  `ContactId` int(11) NOT NULL,
  `PhoneId` smallint(5) unsigned NOT NULL,
  `Status` tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `ContactPhone`
--
ALTER TABLE `ContactPhone`
  ADD PRIMARY KEY (`ContactPhoneId`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `ContactPhone`
--
ALTER TABLE `ContactPhone`
  MODIFY `ContactPhoneId` int(10) unsigned NOT NULL
  AUTO_INCREMENT,AUTO_INCREMENT=1;

我需要根据以下组合条件约束

确保记录
  • ContactId
  • PhoneId
  • Status == 1(值应为1 - 活动记录)

注意:不需要非活动记录(即Status == 0)。我只需要为Active Records提供此约束。

请帮助我如何为上面提出的MySQL表添加这个约束。

1 个答案:

答案 0 :(得分:1)

根据documentation

  

UNIQUE索引允许包含NULL的列的多个NULL值。

如果您使用not null代替{{},那么从Status移除(ContactId,PhoneId,Status) - 约束并在null上添加唯一索引将按您的意愿运行1}}用于非活动记录。

如果您不希望或不能将0用于null列,请确保StatusStatus=0行为相同,或者例如要将Status=null视为活动(并强制执行唯一性),您可以添加一个将从Status=2计算的虚拟列。

如果您使用的是MySQL 5.7+,则可以使用生成的列执行此操作:

Status

否则,您可以使用普通列并使用触发器来计算列的值,例如:

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);的不同值。