MySQL允许一个关系或另一个关系,但不能同时使用两个关系

时间:2016-02-23 15:01:38

标签: mysql

我有以下原理图

Book
    id INT(12), // PK
    title VARCHAR(50),
    isbn VARCHAR(50),
    price VARCHAR(8),
    image VARCHAR(200)

Book_Genre
    book_id INT(12), // COMPOUND KEY also references Book.id
    genre_id INT(12) // COMPOUND KEY also references Genre.id  

Book_Classification
    book_id INT(12), // PK + FK, references Book.id
    classification_id INT(12) // FK, references classification.id

Genre
    id INT(12), // PK
    title VARCHAR(50) 

Classification
    id INT(12), // PK
    classification_type VARCHAR(20),
    classification_description VARCHAR(200),
    classification_value VARCHAR(12)

Book_GenreBook_Classification来自join的{​​{1}}表。从技术上讲,使用当前的方法,如果Book表都填充了join,则Book可以具有类型和分类。这样做的问题在于,具有分类的书被认为是非小说书,而具有类型的书被认为是小说书。

我坚持要保留book_id (Book.id)表,因为它允许我为多个小说类型提供多种类型,即Action&恐怖,它允许我给NonFiction书籍多个分类,例如他们的LOC号和他们的DeweyDecimal值。

如果对另一个表的关系/引用已经存在,是否可以限制对一个表的关系/引用?

澄清: - 我不希望一本书能够被分类,如果它已经有一个类型,我不希望一本书能够被赋予一个类型,如果它已经有一个分类。

(抱歉naff原理图,不在我的工作电脑上)

3 个答案:

答案 0 :(得分:2)

每个Book_GenreBook_Classification表格上的 BEFORE INSERT TRIGGER怎么样?触发器将检查另一个表中是否已存在book_id的关系,如果是,则SIGNAL将出错。

触发器代码可能如下所示:

CREATE TRIGGER ins_Book_Classification BEFORE INSERT ON Book_Classification
FOR EACH ROW
BEGIN
    IF (SELECT COUNT(*) FROM Book_Genre WHERE book_id = NEW.book_id) > 0 THEN
        SIGNAL SQLSTATE '90001'
        SET MESSAGE_TEXT = 'Reference already exists in Book_Genre';
    END IF;
END

(注意:以上代码未经过测试)

有关Trigger syntax的更多信息。

答案 1 :(得分:0)

我猜,您希望使用数据库约束来强制执行您的编目规则,即非小说类书籍不能具有小说类型,小说类书籍也不能具有非小说类别。

MySQL的内置约束功能不够复杂,无法以简单的方式处理您的需求。

您可以构建一个查询,因此可以构建一个VIEW对象,在存在分类时省略类型,反之亦然。但这不会阻止创建破坏编目规则的数据。

您可以构建一个触发器来强制执行此操作。

但最好的办法是在你的应用程序逻辑中加入这样的规则。

答案 2 :(得分:0)

作为您问题的解决方案(因为涉及3个表),您可以在插入Book_GenreBook_Classification表之前编写触发器函数,以检查是否有任何具有相同书籍ID的记录存在于另一个表中,并决定是否应该拒绝该记录。

这有点棘手,您可以参考this question作为示例。