Was ist besser: Fremdschlüssel oder Modellvererbung?

8

Ich habe dieses Anwendungsfall-Szenario: Es gibt Orte, die entweder Spielplätze, Restaurants, Theater, Kneipen sind. das gleiche place kann Spielplätze, Restaurants, Theater usw. haben Es gibt mehrere Möglichkeiten, es zu implementieren:

  1. Verwenden Sie Fremdschlüssel

    %Vor%
  2. Mehrfachvererbung

    %Vor%
  3. Verwenden Sie die abstrakte Klasse

    %Vor%
  4. Verwenden Sie Proxy-Modelle

    %Vor%

Was sind die Vor- und Nachteile der Verwendung jedes Ansatzes?

    
whatf 20.01.2012, 04:31
quelle

4 Antworten

14

Die erste ist im Wesentlichen Modellvererbung, denn das ist es, was Djangos Implementierung von MTI verwendet (außer es ist ein OneToOneField anstelle eines ForeignKey , aber das ist nur ein ForeignKey , das ist einzigartig) .

Immer wenn Sie eine is-a Beziehung haben (d. h. ein Restaurant ist ein Ort), haben Sie es mit der Vererbung zu tun, also ist die Verwendung einer von Djangos Modellvererbungsmethoden der richtige Weg. Jeder hat jedoch seine Vor- und Nachteile:

Abstrakte Modelle

Abstrakte Modelle sind nützlich, wenn Sie nur wiederholte Felder und / oder Methoden ausladen möchten. Sie werden am besten als Mixins verwendet, mehr als wahre "Eltern". Zum Beispiel haben alle diese Modelle eine Adresse, also könnte es nützlich sein, ein abstraktes Address -Modell zu erstellen und jedes davon zu erben. Aber ein Restaurant ist kein Address per se, also ist dies keine echte Eltern-Kind-Beziehung.

MTI (Vererbung mehrerer Tabellen)

Dies ist der, der Ihrer ersten Wahl oben ähnlich ist. Dies ist am nützlichsten, wenn Sie sowohl mit den Eltern- als auch den Kindklassen interagieren müssen und die Kinder eigene Felder haben (Felder, keine Methoden). Ein Restaurant könnte also ein cuisine -Feld haben, aber ein Place würde das nicht benötigen. Beide haben jedoch eine Adresse, also erbt Restaurant und baut von Place ab.

Proxy-Modelle

Proxy-Modelle sind wie Aliase. Sie können keine eigenen Felder haben, sie bekommen nur die Felder des Elternteils. Sie können jedoch ihre eigenen Methoden haben, also sind diese nützlich, wenn Sie Arten der gleichen Sache unterscheiden müssen. Zum Beispiel könnte ich Proxy-Modelle wie StaffUser und NormalUser von User erstellen. Es gibt immer noch nur eine Benutzertabelle, aber ich kann jetzt jedem einzelne Methoden hinzufügen, zwei verschiedene Admin-Ansichten erstellen usw.

Für Ihr Szenario machen Proxy-Modelle keinen Sinn. Die Kinder sind von Natur aus komplizierter als die Eltern und es wäre nicht sinnvoll, alle Felder wie cuisine für Restaurant für Place zu speichern.

Sie könnten ein abstraktes Place -Modell verwenden, aber dann verlieren Sie die Fähigkeit, Place allein zu bearbeiten. Wenn Sie einen Fremdschlüssel für einen verallgemeinerten "Ort" haben möchten, müssen Sie stattdessen generische Fremdschlüssel verwenden, um zwischen den verschiedenen Ortstypen zu wählen, und das fügt viel Overhead hinzu, wenn es nicht notwendig ist.

Ihre beste Wette ist die normale Vererbung: MTI. Sie können dann einen Fremdschlüssel für Place erstellen und alles hinzufügen, das ein Kind von Place ist.

    
Chris Pratt 20.01.2012, 15:59
quelle
1

Es hängt ganz davon ab, welche Art von Verhalten Sie brauchen.

Müssen Sie auf Plätzen, in Restaurants oder auf Spielplätzen die gleichen Operationen durchführen? Werden Sie überprüfen, ob Ihre Dienstleistungen (Restaurants etc.) am gleichen Ort sind? Ist es sinnvoll, zwei Orte mit der gleichen Adresse als unterschiedlich zu behandeln und ihre zugehörigen Dienste als unterschiedlich?

Ohne die Antworten auf diese Art von Fragen zu kennen, ist es unmöglich zu sagen, welche Technik am besten geeignet ist, da es sich um sehr unterschiedliche Techniken handelt, die sich im Allgemeinen nicht gegenseitig ersetzen.

Die Verwendung von Vererbung sollte nicht von einer vorgefassten Vorstellung über Taxonomie diktiert werden, da sie nicht dazu da ist, Taxonomie zu modellieren: Sie dient dazu, Funktionspolymorphie bereitzustellen (Datenelementvererbung gibt es hauptsächlich, um dies zu erleichtern).

    
Marcin 20.01.2012 10:15
quelle
0

Ich würde für eine abstrakte Klasse stimmen, wenn die Domäne vorschreibt, dass ein place nicht existieren kann, wenn es nicht mindestens einer der anderen ist.

Aber wenn ein place nicht benötigt wird, benötigen Sie mehrfache Vererbung, um die Ortsmarker (unbebaute Grundstücke) aufzunehmen?

Ich kann mir vorstellen, dass die Pro und Con's sich um Ihre Vorliebe für falsche Datenbanktabellen drehen. Wie implementiert das ORM diese Lösungen? Persönlich mag ich nicht viele Einzelfeldtabellen, aber ymmv.

    
John Mee 20.01.2012 05:54
quelle
0

Ich würde für die erste Stimme stimmen, weil sie am deutlichsten ist. Und ich sehe keine Vorteile anderer Methoden.

    
DrTyrsa 20.01.2012 07:49
quelle

Tags und Links