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:
Verwenden Sie Fremdschlüssel
%Vor%Mehrfachvererbung
%Vor%Verwenden Sie die abstrakte Klasse
%Vor%Verwenden Sie Proxy-Modelle
%Vor%Was sind die Vor- und Nachteile der Verwendung jedes Ansatzes?
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.
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).
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.
Tags und Links django django-models