DB / performance: mise en page d'un modèle django faisant rarement référence à son parent plus d'une fois

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

Question

J'ai une application qui présente les villes simplifiées fictives.

Veuillez considérer les modèles Django suivants:

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'

Explications relatives au choix de cette configuration:

(1) Chaque ville possède certains bâtiments de type "basique" saisissez exactement une fois par ville (exemples: mairie, caserne de pompiers, commissariat de police, hôpital, école) et éventuellement des dizaines de bâtiments de "extra". type, tels que les clubs de danse.

(2) Dans certaines vues, tous les bâtiments (quelle que soit la ville, etc.) doivent être filtrés en fonction de critères différents, par exemple, other_criterion .

Problème / préoccupation:

Dans une vue city_detail , il me faudrait parcourir en boucle tous les bâtiments de " extra " tapez, ce qui est correct et normal.

Mais je ne suis pas sûr de savoir comment récupérer efficacement le "hôpital" de la ville. bâtiment, qui est de "base" De toute façon, je dois le faire pour chaque ville car il existe exactement un hôpital de ce type dans chaque ville (cela est garanti au moment de la création de la ville).

Il y aura au plus une douzaine de " bases " types de bâtiments, dont environ la moitié sera présentée tout le temps.

Je suis enclin à écrire des méthodes pratiques sur le modèle City, et je suis confronté à trois options:

(A1) Via , essayez et index: .filter (...) [0]

(A2) Via essayer et .get (...)

(A3) Via , essayez et .filter (...). latest ()

Mais aucun de ceux-ci ne semble élégant. Ou bien l’une de ces trois options peut-elle être combinée à une sorte de mise en cache, comme dans la méthode get_profile () de Django sur le modèle Utilisateur ? Malheureusement, je n'ai pas encore d'expérience en cache.

Est-ce que c'est fou d'utiliser l'option suivante?

(B) FK spécifiques dans le modèle de ville, un pour chacun des types de base les plus importants

Question:

Quelle option est la plus logique?
Ou bien le schéma est-il généralement défectueux pour ce genre de scénario?

Que proposez-vous en particulier en ce qui concerne les performances de base de données? Ai-je besoin d'une approche complètement différente?

S'il vous plaît aviser! :)

Merci d'avance!

Était-ce utile?

La solution

Si une ville ne peut pas avoir plus d'un hôtel de ville, caserne de pompiers, poste de police, hôpital, école, etc., je pense que le moyen le plus simple de l'appliquer est de déclarer chacun d'eux comme un champ du modèle:

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

Si vous trouvez cela aussi "désordonné" dans votre modèle de ville, vous pouvez envisager de créer un modèle CityBuildings intermédiaire:

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)

Vous faites ensuite référence aux bâtiments comme, par exemple, city.buildings.fire_station

Ce ne sont que des suggestions ... Je ne sais pas si l'une ou l'autre solution est plus "correcte"

Autres conseils

Pour tous ceux qui sont intéressés: stupide, j'ai découvert l’existence de la technique de mémorisation, c’est pourquoi je vais utiliser une forme de celle appliquée à (A2), englobée dans autant de méthodes pratiques que sur le modèle City "basique". types de bâtiments.

Cela est au moins un peu moins compliqué que d'avoir des FK dans deux directions et permet au code d'être plus clair sur la séparation des intérêts (modélisation d'un côté, performances de l'autre).

Sur le vif, j’ai élaboré deux projets à étudier en matière d’apprentissage et éventuellement de prêt ou d’application directe:

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

Peut-être que quelqu'un trouvera cela utile également.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top