2012-12-12 18 views
21

Ich modelliere eine Viele-zu-Viele-Beziehung, bei der die Beziehung meistens nur von einer Seite aufgerufen wird. Es ist eher eine Hierarchie, auf die von oben nach unten zugegriffen wird und nicht umgekehrt.Junction-Tabellen vs Fremdschlüssel-Arrays?

Umfrage hat und gehört zu vielen Fragen hat und gehört zu vielen Antworten.

Beide Beziehungen müssen viele-zu-viele sein, weil dieselbe Frage in verschiedenen Umfragen und derselben Antwort in vielen Fragen wiederverwendet werden kann. Dies ist eine Voraussetzung.

Die Standard-M2M-Implementierung würde zwei Junction-Tabellen verwenden, surveys_questions und questions_answers. Stattdessen denke ich über PostgreSQL Integer-Arrays zu speichern question_ids in Survey und answer_ids in Frage.

Wir können den Operator ANY verwenden, um alle Zeilen abzufragen, die mit dem Fremdschlüsselarray übereinstimmen.

Wie würden wir alle Umfragen mit ihren Fragen und Fragen mit SQL Abfragen?

Wie können wir die Reihenfolge der Zeilen anpassen, die mit dem Fremdschlüsselarray zurückgegeben werden? dh. Mit question_ids = [1,2,3] werden Fragezeilen mit der Reihenfolge 1, 2, 3 garantiert.

Wie funktioniert dies leistungsmäßig im Vergleich zu Junction-Tabellen (unter der Annahme von richtigen Indizes, was auch immer sie sein mögen)?

Würden Sie das vorschlagen? Gibt es einige Ressourcen zur Modellierung von M2M?

aktualisieren

Es gab einen Vorschlag referentielle Integrität für Array Fremdschlüssel zu PostgreSQL 9.3 hinzuzufügen, aber es hat nicht inbegriffen erhalten: http://blog.2ndquadrant.com/postgresql-9-3-development-array-element-foreign-keys/

SO Frage über Auftrag Fremdschlüssel Array Aufrechterhaltung PostgreSQL JOIN with array type with array elements order, how to implement?

+0

Sie sagen viele zu viele, aber das klingt wie eins zu vielen; Viele zu viele würden bedeuten, dass sich jede Umfrage auf mehrere Fragen bezieht und jede Frage sich auf mehrere Umfragen bezieht, aber das hört sich ein wenig merkwürdig an, sicher, die Art, wie Sie es formulierten "hat-viele" ist normalerweise gleichbedeutend mit eins zu vielen (viele-zu -many wird normalerweise 'has-and-goes-to-many' genannt) – SingleNegationElimination

+0

@TokenMacGuy: Sorry für die Verwirrung. Fragen können in Umfragen und Antworten quer durch alle Fragen wiederverwendet werden, wodurch die Beziehungen von Mensch zu Mensch entstehen. Ich ersetze die Beziehung mit HABTM. – randomguy

Antwort

7

Verwenden Sie den Junction-Table-Ansatz. Die Array-Methode ist nicht Standard genug, dass Sie Fragen stellen müssen, wie viel es funktionieren würde, während das andere vollständig Standard ist.

+4

Junction-Tabellen können jedoch erheblich langsamer als Arrays sein. siehe https://gist.github.com/joevandyk/031cf5812bd656887623 –

+0

Ja, manchmal gibt es eine Leistungssteigerung von der Array-Methode. Es gibt eine große Frage darüber, ob es für alle Situationen natürlich bestehen würde, und eines der Hauptprobleme besteht darin, dass das Hinzufügen/Entfernen eines neuen Links eine Änderung an einer möglicherweise langen Reihe (Coupon, in dem Beispiel) anstelle des Einfügens/Löschens erfordert einer einzelnen Reihe und eine Sperre auf der Kuponentabelle. –

+0

Einverstanden! Wenn Sie die Coupons-Tabelle nicht bei jeder Einfügung ändern möchten, können Sie stattdessen eine coupons_products_array-Tabelle (coupon_id, product_ids []) verwenden. Aber das könnte albern werden. –