2017-03-06 6 views
0

Während db design habe ich folgenden Fall gefunden und bin mir nicht sicher, ob ich das richtig gehandhabt habe. So gibt es meine Db-Schema:Fremdschlüssel - Datenbankentwurf

enter image description here

Dieses Schema enthält Daten über Produkte, die auf bestimmten Servern. Der Server kann für mehrere Kunden freigegeben werden. Tabelle ProductServer teilt uns mit, dass das angegebene Produkt auf dem angegebenen Server installiert wurde.

Da die Kombination aus Produkt/Server von mehreren Kunden verwendet werden kann (der Server kann mehrere Kunden haben), habe ich eine weitere Tabelle Instance erstellt, die zusätzliche Informationen zur ProductServer-Zeile enthält. Es enthält Informationen darüber, welcher Kunde dieses Produkt und seine Priorität verwendet.

Ich verwende kein Persistence-Framework, also schrieb ich alle Funktionen zum Holen manuell.

Mein Problem ist: Ich habe zur Zeit Abfrage, die alle Tabellen verknüpft:

SELECT * FROM ProductServer ps 
LEFT OUTER JOIN Product p ON ps.product_id = p.product_id 
LEFT OUTER JOIN Server s ON ps.server_id = s.server_id 
LEFT OUTER JOIN ServerCustomer sc ON s.server_id = sc.server_id 
**LEFT OUTER JOIN Customer c ON sc.customer_id = c.customer_id** 
LEFT OUTER JOIN Instance i ON ps.ps_id = i.ps_id 
**LEFT OUTER JOIN Customer c2 ON i.customer_id = c2.customer_id** 

In meinem SQL können Sie sehen, Reihen mit ** gekennzeichnet, ich in einer Abfrage einer Tabelle zweimal zu verbinden hatte, Ich bin mir nicht ganz sicher, aber ich denke, dass dies eine schlechte Idee/ein schlechtes Design von db sein kann.

Ich hatte eine Idee, ProductServer und Instance in eine Tabelle aufzuteilen, aber da die ProductServer-Tabelle vielleicht 100k Zeile hat, fühlte ich, dass es besser ist, diese Tabelle auf zwei kleinere Tabellen aufzuteilen.

Bitte können Sie mir sagen, ob dies schlecht entworfen ist und an einige Quellen weiterleiten, wo ich herausfinden kann, wie dieses Problem besser umgesetzt wird?

Bearbeiten: Ich muss alle Kunden für bestimmte Server holen, weil ich alle Daten zu Java-Objekt holen muss. Deshalb brauche ich Tabelle Kunde trat mit ServerCustomer und auch Kunde mit Instanz Tabelle in einer Datenbankabfrage verbunden.

Antwort

0

Was Sie tun können, ist, Ihre Joins neu anzuordnen und nur zu Customer einmal beizutreten. Nicht ganz klar, ob Ihre aktuellen Bedingungen durch eine AND oder eine OR kombiniert werden sollten. Ich werde mit AND hier:

SELECT * FROM ProductServer ps 
LEFT OUTER JOIN Product p ON ps.product_id = p.product_id 
LEFT OUTER JOIN Server s ON ps.server_id = s.server_id 
LEFT OUTER JOIN ServerCustomer sc ON s.server_id = sc.server_id 
LEFT OUTER JOIN Instance i ON ps.ps_id = i.ps_id 
LEFT OUTER JOIN Customer c ON sc.customer_id = c.customer_id 
          AND i.customer_id = c.customer_id 

Sie tun dies, weil schließt sich nicht unbedingt zwischen zwei Tabellen - sie sind zwischen Tabellenquellen, die können sich bereits das Ergebnis von anderen verbindet. Wenn wir oben die letzte ON-Klausel erreichen, treten wir rechts auf {ProductServer, Server, ServerCustomer, Instance} auf {Customer} auf, und wir können auf alle Spalten aus diesen Tabellen als Teil unserer Join-Bedingungen verweisen.

+0

Der Grund, warum ich diese beiden Joins machte, ist, dass ich diese Abfrage verwende, um alle diese Daten in Java-Objekte abzurufen. Also muss ich alle Kunden Objekt in Server-Objekt haben, und ich muss auch Kundenobjekt in Instanz Objekt haben. – n0hepe