2017-02-25 139 views
0

可以說有三個表稱爲教師,學生和消息。Mysql外鍵引用兩個列,它們是兩個不同表中的主鍵

教師:

----------- 
ID | name | 
----------- 
t_1| Dani | 
----------- 
t_2| Billy| 
----------- 

學生:

------------- 
ID | name | 
------------- 
s_1| Luckas | 
------------- 
s_2| Oliver | 
------------- 

消息:

-------------------------------- 
| ID | sender_ID | receiver_ID | 
-------------------------------- 
| 1 | s_1  | s_2   | 
-------------------------------- 
| 2 | s_1  | t_1   | 
-------------------------------- 
| 3 | s_1  | t_2   | 
-------------------------------- 
| 4 | t_1  | s_2   | 
-------------------------------- 

抱歉表看起來如何,我不知道該怎麼做更好。

我希望只有來自教師或學生的值才能被允許存儲在messages.sender_id和messages.receiver_Id中,就像在FK的情況下一樣。

我需要知道它是否可行,如果是這樣,怎麼樣?

+0

你的意思是學生或老師可以既是發送方或接收? – Oscar

+0

是的,我該怎麼做? – Orih90

+0

在這種情況下,您不能使用外鍵。外鍵引用單個表中的字段。您可以使用觸發器來強制執行數據完整性 – Shadow

回答

1

你有兩種不同的選擇。 首先是創建一個Person表,另一個PersonType。 PersonType將包含「學生」和「教師」作爲值。將PersonTypeId添加到Person併爲PersonType創建一個外鍵,這將作爲學生和教師之間的區分對象。將外鍵添加到來自Person的Messages表中。

第二個是創建「數據庫繼承」。使用學生和教師之間的共同數據創建Person表。然後,使用每個人的特定數據創建Students and Teachers表,並在兩者上爲Person添加一個外鍵。將您的外鍵添加到來自Person表的消息。 第一個解決方案更高性能。

0

MySQL不支持聲明式外鍵約束來強制執行此完整性規則。使用所示的表格(即不改變表格),我們可以使用觸發器來執行這些類型的參照完整性規則。這將需要在所有三個表上進行BEFORE INSERT,BEFORE UPDATE和BEFORE DELETE觸發器的組合。

我們沒有看到任何規則會阻止同一個值(例如,k_9)出現在studentteacher表中。因此,有sender_ID的消息中的一行是k_9,我們無法確定哪一個是指的,studentteacher或兩者。


如果有可能改變表定義,我們可以實現一個person表爲studentteacher一個超類。一對夫婦模式來實現這一點。一種可能是添加鑑別器列。

person 
ID type  name 
--- ------- ------ 
s_1 student Lukas 
s_2 student Oliver 
t_1 teacher Dani 
t_2 teacher Billy 
k_9 student Rover 

使用該表,從messages聲明外鍵約束將很簡單。

我們可以返回students表的原始設計等價和teachers表:

學生

SELECT ID, name FROM person WHERE type = 'student' 

教師

SELECT ID, name FROM person WHERE type = 'teacher' 

但只給三問題中顯示的表格,這是不可能的o聲明外鍵約束來執行指定的參照完整性規則。執行這些完整性規則的唯一方法是通過觸發器。

BEFORE INSERT ON messages 
FOR EACH ROW 
BEGIN 
    -- if NEW.sender_ID is non-NULL, verify the value appears 
    -- as value in `ID` column of either `students` or `teachers` 
    -- if not, throw an error 

    -- if NEW.receiver_ID is non-NULL, verify the value appears 
    -- as value in `ID` column of `students` or `teachers` 
    -- if not, throw an error 

END 

我們還需要爲UPDATE上的消息觸發,以及更新和刪除學生和教師

相關問題