2016-02-23 42 views
1

我有以下示意圖的MySQL允許一個關係或其他關係,但不能同時爲同一ID

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充當從Bookjoin表。從技術上講,採用這種當前方法,如果兩張join表格都填充了book_id (Book.id),則圖書可以具有流派和分類。問題在於一本有分類的書被認爲是一部非文學書,而一本具有流派的書被認爲是一本小說書。

我在保持join表,因爲它可以讓我給多小說類書籍多個流派,即行動&恐怖堅持,它允許我給非小說類書籍多個類別,如他們的LOC數及其DeweyDecimal值。

如果對另一個表的關係/引用已經存在,是否可以限制關係/對一個表的引用?

澄清: - 我不希望一本書如果它已經有一個流派,就不能給它一個分類,並且我不希望一本書能夠得到一個流派,如果它已經有一個分類。

(很抱歉的蹩腳的原理,而不是我的工作PC)

+0

這個限制不能在具有聲明性約束的MySQL數據庫中強制執行;爲了讓MySQL執行這種限制,您必須在兩個關係表上添加BEFORE INSERT/BEFORE UPDATE觸發器。 – spencer7593

+0

我甚至都沒有意識到這些觸發器存在,直到有人在這裏發佈它 - 這是一個理想的概念,所以非常感謝你和其他人提供這些觸發器,因爲它們對於我正在嘗試做的事實際上非常有用! @ spencer7593 –

回答

2

怎麼樣上BEFORE INSERTTRIGGER每個Book_GenreBook_Classification表。該觸發器將檢查另一個表中是否已存在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

更多信息。

0

你是,我想,希望使用一個數據庫約束來您的編目規則,非小說類書籍不能有小說流派和小說類書籍不能有非小說類別。

MySQL的內置約束功能不夠複雜,無法以簡單的方式處理您的需求。

您可能可以構建查詢,因此可以構建一個VIEW對象,該對象在存在分類時會省略流派,反之亦然。但是這不會阻止創建破壞編目規則的數據。

您可能可以構建觸發器來執行此操作。

但是你最好的辦法是在你的應用程序邏輯中加入這樣的規則。

+0

我認爲這可能是在應用程序邏輯中這樣做的一個例子,可能最好問一下。無論如何,我會看看使用'VIEW'對象,因爲我以前從未看過這些對象。是的 - 你對答案開始的假設是正確的。 –

0

至於你的問題的解決方案(因爲它涉及到3個表),你可以寫在插入之前觸發功能分爲Book_GenreBook_Classification表,如果與同一本書ID的任何記錄在另一表中存在哪些會檢查並決定是否該記錄應該被拒絕。

這有點棘手,你可以參考this question作爲一個例子。

相關問題