DB / Leistung: Layout django Modell, das mehr an ihre Mutter bezieht sich selten als einmal
-
10-07-2019 - |
Frage
Ich habe eine Anwendung, die über präsentiert fiktive vereinfachte Städte ist.
Bitte beachten Sie folgende Django Modelle:
class City(models.Model):
name = models.CharField(...)
...
TYPEGROUP_CHOICES = (
(1, 'basic'),
(2, 'extra'),
)
class BldgType(models.Model):
name = models.CharField(...)
group = models.IntegerField(choices=TYPEGROUP_CHOICES)
class Building(models.Model):
created_at = models.DateTimeField(...)
city = models.ForeignKey(City)
type = models.ForeignKey(BldgType)
other_criterion = models.ForeignKey(...)
class Meta:
get_latest_by = 'created_at'
Erläuterungen für die Wahl dieses Setup:
(1) Jede Stadt hat bestimmte Gebäude eines „basic“ Typs, der genau einmal auftritt pro Stadt (Beispiele: Rathaus, Feuerwehr, Polizei, Krankenhaus, Schule) und möglicherweise Dutzende von Gebäuden von „extra“ Typ, wie Tanzclubs.
(2) In bestimmten Ansichten, alle Gebäude (unabhängig von der Stadt, etc.) werden nach verschiedenen Kriterien gefiltert werden, beispielsweise other_criterion
.
Problem / Anliegen:
In einer city_detail
Ansicht, würde ich über alle Gebäude von „extra“ Typ Schleife hat, die in Ordnung und normal ist.
Aber ich bin nicht sicher, wie effizient das „Krankenhaus“ Gebäude der Stadt abzurufen, die von „basic“ Typ ist, also muss ich dies ohnehin für jede Stadt, weil genau ein solches Krankenhaus in jeder Stadt existiert (dies gewährleistet ist bei Stadt Erstellungszeit).
Es wird ein Dutzend von „basic“ Gebäudetypen höchstens sein, von denen etwa die Hälfte wird die ganze Zeit präsentiert.
Ich bin geneigt zu Convenience-Methoden auf dem Stadtmodell zu schreiben, und ich stelle drei Möglichkeiten:
(A1) Via try
und Index: .filter(...)[0]
(A2) Via try
und .get(...)
(A3) Via try
und .filter(...).latest()
Aber keiner von denen scheint elegant.
Oder ist eine dieser drei Optionen gut mit irgendeiner Art von Caching zu kombinieren, wie in Djangos get_profile()
Methode auf dem User
Modell? Leider habe ich keine Erfahrung mit Caching noch.
Ist es Nüsse die folgende Option zu benutzen?
(B) spezifische FKs im Stadtmodell, ein für jede der wichtigsten Grundtypen
Frage:
Welche Option ist sinnvoll, die meisten?
Oder ist das Schema der Regel fehlerhafte für diese Art von Szenario?
Vor allem DB Leistung in Bezug auf, was schlagen Sie vor? Muss ich einen völlig anderen Ansatz?
Bitte geben! :)
Vielen Dank im Voraus!
Lösung
Wenn eine Stadt kann nicht mehr hat, als ein jeder von Rathaus, Feuerwehr, Polizei, Krankenhaus, Schule etc. dann denke ich, der einfachste Weg, dies zu erzwingen ist jeder als ein Feld auf dem Modell zu erklären:
class City(models.Model):
name = models.CharField(...)
city_hall = models.ForeignKey(Building)
fire_station = models.ForeignKey(Building)
# ... et cetera
Wenn Sie dies zu „chaotisch“ in Ihrem Stadtmodell finden, könnten Sie ein Zwischen CityBuildings
Modell berücksichtigen zu müssen:
class CityBuildings(models.Model):
city_hall = models.ForeignKey(Building)
fire_station = models.ForeignKey(Building)
# ... et cetera
class City(models.Model):
name = models.CharField(...)
buildings = models.OneToOneField(CityBuildings)
Dann beziehen Sie sich auf Gebäude wie zum Beispiel city.buildings.fire_station
Dies sind nur Vorschläge ... Ich bin nicht sicher, ob so oder so mehr „richtige“
istAndere Tipps
Für alle, die interessiert: silly mir die Existenz der memoization Technik entdeckt, so dass ich, dass irgendeine Form von bis (A2) aufgebracht verwenden, in so viele bequemen Methoden auf dem Modell der Stadt eingewickelt, wie ich „basic“ Gebäudetyp habe .
Dies ist zumindest etwas weniger chaotisch als FKs in zwei Richtungen mit und lässt den Code über die Trennung der Interessen klarer sein (Modellierung auf der einen Seite, die Leistung auf der anderen Seite).
Auf dem schnellen, machte ich zwei Projekte aus um für das Lernen zu suchen und möglicherweise Sachen Kreditvergabe oder die Anwendung direkt:
- django-memoize
- github.com/husio/django-easycache /
Mayhaps jemand auch diese nützlich finden.