我有以下原理图
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_Genre
和Book_Classification
来自join
的{{1}}表。从技术上讲,使用当前的方法,如果Book
表都填充了join
,则Book可以具有类型和分类。这样做的问题在于,具有分类的书被认为是非小说书,而具有类型的书被认为是小说书。
我坚持要保留book_id (Book.id)
表,因为它允许我为多个小说类型提供多种类型,即Action&恐怖,它允许我给NonFiction书籍多个分类,例如他们的LOC号和他们的DeweyDecimal值。
如果对另一个表的关系/引用已经存在,是否可以限制对一个表的关系/引用?
澄清: - 我不希望一本书能够被分类,如果它已经有一个类型,我不希望一本书能够被赋予一个类型,如果它已经有一个分类。
(抱歉naff原理图,不在我的工作电脑上)
答案 0 :(得分:2)
每个Book_Genre
和Book_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_Genre
和Book_Classification
表之前编写触发器函数,以检查是否有任何具有相同书籍ID的记录存在于另一个表中,并决定是否应该拒绝该记录。
这有点棘手,您可以参考this question作为示例。