如何在MySQL中为该条件添加约束?

如何在MySQL中为该条件添加约束?,mysql,sql,database-design,foreign-keys,constraints,Mysql,Sql,Database Design,Foreign Keys,Constraints,我的桌子看起来像这样: CREATE TABLE IF NOT EXISTS `entry_title` ( `entry_title_id` int(11) NOT NULL AUTO_INCREMENT, `entry_id` int(11) NOT NULL, `accepted` tinyint(1) DEFAULT NULL, `entry_title_lang` char(2) CHARACTER SET ascii NOT NULL, `entry_title_

我的桌子看起来像这样:

CREATE TABLE IF NOT EXISTS `entry_title` (
  `entry_title_id` int(11) NOT NULL AUTO_INCREMENT,
  `entry_id` int(11) NOT NULL,
  `accepted` tinyint(1) DEFAULT NULL,
  `entry_title_lang` char(2) CHARACTER SET ascii NOT NULL,
  `entry_title_value` varchar(255) NOT NULL,
  `entry_title_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`entry_title_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
表中的一行表示网站内容的标题

这个想法是,任何人都可以提交一个新的(有望改进的)标题

然后社区接受或放弃更改

如果接受标志等于
NULL
,则表示社区正在等待更改的审核。0被解释为已放弃,1被解释为已接受

网站显示带有最新
时间戳的标题,其中接受的标志等于
1

当变更待审核时,在待审核变更被接受或拒绝之前,不得提交其他变更

因此,我希望在数据库中设置一个约束,确保每个
条目id
中只有行
的值为
NULL

我考虑使用一个单独的字段
pending\u review
,它要么是
1
要么是
NULL
,并将唯一的约束与
entry\u id
结合使用

问题是,当更改被接受或拒绝时,我需要以某种方式取消设置该字段,而该级别的一致性需要另一个约束,这种约束会导致与上述更简单的解决方案相同的问题。

[更新] 在标准驱动的理想世界中:

CHECK(NOT EXISTS(SELECT 1 FROM entry_title WHERE accepted IS NULL GROUP BY entry_id HAVING COUNT(*) > 1))
唉,我们生活在一个不完美的世界里。看到这个了吗

因此,请使用具有相同逻辑的触发器

[更新-触发]

差不多

CREATE TRIGGER triggerName BEFORE INSERT ON entry_title FOR EACH ROW
BEGIN
    IF EXISTS(SELECT 1 FROM entry_title 
              WHERE accepted IS NULL AND entry_id = NEW.entry_id 
              GROUP BY entry_id 
              HAVING COUNT(*) > 1) THEN
        SIGNAL SQLSTATE '45000'
    END IF;
END
在更新之前也要做同样的事情。
免责声明,我没有对此进行检查。

wups,请阅读MySQL文档:“check子句已解析,但被所有存储引擎忽略。”真倒霉。使用更好的工具,如PostgreSQL^^编辑:看起来PostgreSQL也不支持check中的子查询。是的,我正好碰到了那堵墙,但不确定原因。不幸的是,我不太熟悉mysql触发器(输入/输出参数、返回值、何时调用等等),只是更新了我的答案。该信号sqlstate返回一个错误,将导致相应的操作失败。我现在不能测试这个,所以请你自己检查一下。你需要保留过去头衔的历史记录吗?或者仅仅拥有一个“当前”标题和一个可选的“待定”标题就足够了?我想保留一个历史记录。因为我希望投票的条件变得更加困难,基于对数函数,超过已经提交的标题的数量。。。