【问题标题】:Can MySQL constrain based on a NULL value combined with an id?MySQL 可以基于 NULL 值和 id 进行约束吗?
【发布时间】:2012-03-27 17:01:12
【问题描述】:

我使用 django-mptt 在 web 应用程序中的模型上创建树结构。

不幸的是 - 有时我会在树中得到重复的根节点。

这些将具有 NULL 作为 parent_id,并且具有相同的 tree_id,如下所示:

+--------+-----------+---------+
| id     | parent_id | tree_id |
+--------+-----------+---------+
| 159092 |      NULL |   52098 | 
| 159093 |      NULL |   52098 | 
+--------+-----------+---------+

有没有办法在数据库级别阻止这种情况?
我可以在 MySQL 中做一个约束来避免获得两个或多个 NULL 作为 parent_id 和相同 tree_id 的项目吗?

models.py 中删除了不相关字段的模型:

class Message(MPTTModel):
    # Threaded messages
    text = textmodels.TextField()

【问题讨论】:

  • 你能显示这个表的models.py文件吗?
  • @Rajeev - 我已经用 models.py 中的最小模型更新了我的问题。

标签: mysql django-mptt


【解决方案1】:

简单的答案是否定的,但您可以创建将阻止新值的插入和更新触发器。如果您使用的是 MySQL >= 5.5,则可以使用类似的东西 -

DELIMITER |

DROP TRIGGER IF EXISTS before_msg_insert|

CREATE TRIGGER before_msg_insert BEFORE INSERT ON message
FOR EACH ROW
BEGIN
    DECLARE xid INT DEFAULT 0;
    IF (NEW.parent_id IS NULL) THEN

        SET xid = (SELECT id FROM message WHERE tree_id = NEW.tree_id AND parent_id IS NULL);

        IF (xid > 0) THEN
            SET @msg = CONCAT("Root node already exists. ID: ", xid);
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @msg;
        END IF;

    END IF;
END|

DROP TRIGGER IF EXISTS before_msg_update|

CREATE TRIGGER before_msg_update BEFORE UPDATE ON message
FOR EACH ROW
BEGIN
    DECLARE xid INT DEFAULT 0;
    IF (NEW.parent_id IS NULL) THEN

        SET xid = (SELECT id FROM message WHERE tree_id = NEW.tree_id AND id <> NEW.id AND parent_id IS NULL);

        IF (xid > 0) THEN
            SET @msg = CONCAT("Root node already exists. ID: ", xid);
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @msg;
        END IF;

    END IF;
END|

DELIMITER ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    相关资源
    最近更新 更多