2017-02-25 3 views
0

Sagen wir, dass es drei Tabellen gibt, die Lehrer, Schüler und Nachrichten genannt werden.Mysql Fremdschlüssel, der einen Verweis auf zwei Spalten hat, die Primärschlüssel in zwei verschiedenen Tabellen sind

Lehrer:

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

Studenten:

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

Nachrichten:

-------------------------------- 
| 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   | 
-------------------------------- 

traurig darüber, wie die Tabellen sieht ich nicht weiß, wie es besser zu machen.

Ich möchte, dass nur Werte von Lehrern oder von Studenten in messages.sender_id und in messages.receiver_Id wie in Fällen von FK gespeichert werden dürfen.

Ich muss wissen, ob es möglich ist und wenn ja, wie?

+0

Sie meinen, dass die Schüler oder Lehrer beide Sender oder Empfänger sein könnte? – Oscar

+0

ja, wie kann ich es tun? – Orih90

+0

Sie können in diesem Fall keine Fremdschlüssel verwenden. Fremdschlüssel verweist auf Felder in einer einzelnen Tabelle. Sie können Trigger verwenden, um die Datenintegrität zu erzwingen – Shadow

Antwort

1

Sie haben zwei verschiedene Möglichkeiten. Zuerst erstellen Sie eine Personentabelle und einen weiteren PersonType. PersonType enthält "Student" und "Lehrer" als Werte. Fügen Sie der Person eine PersonTypeId hinzu und erstellen Sie einen Fremdschlüssel für PersonType. Dies dient als Unterscheidungsmerkmal zwischen Schülern und Lehrern. Fügen Sie den Fremdschlüssel der Nachrichtentabelle von Person hinzu.

Die zweite besteht darin, "Datenbankvererbung" zu erstellen. Erstellen Sie die Personentabelle mit gemeinsamen Daten zwischen Schülern und Lehrern. Erstellen Sie dann die Tabelle "Students and Teachers" (Schüler und Lehrer) mit den spezifischen Daten für jedes Element und fügen Sie bei beiden Personen einen Fremdschlüssel zu Person hinzu. Fügen Sie Ihren Fremdschlüssel Nachrichten aus der Personentabelle hinzu. Erste Lösung ist leistungsfähiger.

0

MySQL unterstützt keine deklarative Fremdschlüsseleinschränkung, um diese Integritätsregel zu erzwingen. Mit den Tabellen wie gezeigt (d. H. Ohne Änderungen an den Tabellen) könnten wir Trigger verwenden, um diese Arten von referenziellen Integritätsregeln zu erzwingen. Es würde eine Kombination aus BEFORE INSERT-, BEFORE UPDATE-, BEFORE DELETE-Triggern für alle drei Tabellen erfordern.

Es wird keine Regel angezeigt, die verhindert, dass derselbe Wert (z. B. k_9) sowohl in der Tabelle student als auch in der Tabelle teacher erscheint. So eine Zeile in Nachrichten, die eine sender_ID hat, ist k_9, hätten wir keine Möglichkeit zu bestimmen, was das betrifft, die student, die teacher oder beides.


Wenn es möglich ist, die Tabellendefinitionen zu ändern, könnten wir eine person Tabelle als übergeordnete Klasse von student und teacher implementieren. Ein paar Muster, um das zu implementieren. Eine Möglichkeit ist das Hinzufügen einer Diskriminatorsäule.

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

Mit dieser Tabelle erklärt für Fremdschlüssel aus der messages würde einfach sein.

Wir haben das Äquivalent der students Tabelle und die teachers Tabelle in der ursprünglichen Entwurf zurückkehren können:

Studenten

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

Lehrer

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

Aber da nur die drei Tabellen in der Frage gezeigt, ist es nicht möglich, t o Deklarieren von Fremdschlüsseleinschränkungen zum Erzwingen der angegebenen referenziellen Integritätsregeln. Der einzige Weg, um diese Art von Integritätsregeln zu erzwingen, wäre durch Trigger.

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 

Wir auch Auslöser für UPDATE ON Nachrichten benötigen würde, sowie UPDATE und DELETE ON Schüler und Lehrer

Verwandte Themen