【问题标题】:How can I add a constraint to this condition in MySQL?如何在 MySQL 中为此条件添加约束?
【发布时间】:2012-06-16 06:25:39
【问题描述】:

我的表格如下所示:

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 被接受。

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

当一项更改处于待审核状态时,在待处理的更改被接受或拒绝之前,我无法提交其他更改。

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

我考虑过使用单独的字段pending_review,即1NULL,并结合entry_id 对其设置唯一约束。

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

【问题讨论】:

  • 您需要保留过去标题的历史吗?还是只拥有一个“当前”标题和可选的另一个“待定”标题就足够了?
  • 我想保留历史记录。因为我希望投票的条件变得更加困难,基于对该条目已提交标题数量的对数函数...

标签: mysql sql database-design foreign-keys constraints


【解决方案1】:

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

CHECK(NOT EXISTS(SELECT 1 FROM entry_title WHERE accepted IS NULL GROUP BY entry_id HAVING COUNT(*) > 1))

唉,我们生活在不完美的世界里。看到这个question

所以使用具有相同逻辑的触发器。

[更新-触发器]

类似

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 也不支持检查子查询。
  • 是的,我正好撞到了那堵墙,但不确定原因。不幸的是,我不太熟悉 mysql 触发器(输入/输出参数、返回值、何时调用等)
  • 刚刚更新了我的答案。那个信号 sqlstate 返回了一个错误,会导致相应的操作失败。我现在无法测试,所以请自己检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2014-06-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
相关资源
最近更新 更多