DB / performance: layout del modello django che raramente si riferisce al suo genitore più di una volta

StackOverflow https://stackoverflow.com/questions/1821778

Domanda

Ho un'app per presentare città semplificate immaginarie.

Ti preghiamo di considerare i seguenti modelli Django:

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'

Spiegazioni per la scelta di questa configurazione:

(1) Ogni città ha determinati edifici di una "base" tipo che si verificano esattamente una volta per città (esempi: municipio, caserma dei pompieri, stazione di polizia, ospedale, scuola) e possibilmente dozzine di edifici di "extra"; tipo, ad esempio discoteche.

(2) In determinate viste, tutti gli edifici (indipendentemente dalla città, ecc.) devono essere filtrati in base a criteri diversi, ad esempio other_criterion .

Problema / riguardano:

In una vista city_detail , dovrei passare in rassegna tutti gli edifici di " extra " digitare, che è OK e normale.

Ma non sono sicuro di come recuperare in modo efficiente l'ospedale della città edificio, che è di "base" tipo, quindi devo farlo per ogni città perché esiste esattamente un ospedale di questo tipo in ogni città (questo è garantito al momento della creazione della città).

Ci saranno al massimo una dozzina di "base". tipi di edifici, di cui circa la metà saranno presentati in ogni momento.

Sono propenso a scrivere metodi di praticità sul modello City e ho tre opzioni:

(A1) Via prova e indicizza: .filter(...)[0[

(A2) Via prova e .get(...)

(A3) Via provare e .filter(...).latest()

Ma nessuno di questi sembra elegante. Oppure una di queste tre opzioni è buona da combinare con una sorta di cache, come nel metodo get_profile () di Django sul modello User ? Sfortunatamente, non ho ancora esperienza con la memorizzazione nella cache.

È pazzesco usare la seguente opzione?

(B) specifici FK nel modello City, uno per ciascuno dei più importanti tipi base

Domanda:

Quale opzione ha più senso?
O lo schema è generalmente difettoso per questo tipo di scenario?

Soprattutto per quanto riguarda le prestazioni del DB, cosa mi consigliate? Ho bisogno di un approccio completamente diverso?

Si prega di avvisare! :)

Grazie in anticipo!

È stato utile?

Soluzione

Se una città non può avere più di una ciascuna per municipio, caserma dei pompieri, stazione di polizia, ospedale, scuola ecc., penso che il modo più semplice per far rispettare ciò sia dichiarare ognuno come un campo sul modello:

class City(models.Model):
    name = models.CharField(...)
    city_hall = models.ForeignKey(Building)
    fire_station = models.ForeignKey(Building)
    # ... et cetera

Se lo trovi anche " disordinato " nel tuo modello di città, potresti prendere in considerazione un modello CityBuildings intermedio:

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)

Quindi ti riferisci agli edifici come, ad esempio, city.buildings.fire_station

Questi sono solo suggerimenti ... Non sono sicuro che in entrambi i casi sia più "corretto"

Altri suggerimenti

Per chiunque sia interessato: sciocco mi ha scoperto l'esistenza della tecnica di memoization, quindi userò una qualche forma di quella applicata a (A2), racchiusa in tanti metodi di convenienza sul modello City quanti ne ho "base" tipi di edifici.

Questo è almeno un po 'meno disordinato rispetto agli FK in due direzioni e consente al codice di essere più chiaro sulla separazione degli interessi (modellazione da un lato, performance dall'altro).

In fretta, ho realizzato due progetti per studiare l'apprendimento e possibilmente prestare materiale o fare domanda direttamente:

  1. django-memoize
  2. github.com/husio/django-easycache /

Forse qualcuno lo troverà utile anche.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top