DB / performance: Disposição de Django modelo que raramente se refere a seu pai mais de uma vez

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

Pergunta

Eu tenho um aplicativo que é cerca apresentando cidades ficcional simplificado.

Por favor, considere os seguintes modelos do 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'

As explicações para escolher esta configuração:

(1) Cada cidade tem alguns edifícios de um tipo "básico" que ocorrem exatamente uma vez por cidade (exemplos: prefeitura, corpo de bombeiros, delegacia, hospital, escola) e, possivelmente dezenas de edifícios do tipo "extra", tais como clubes de dança.

(2) Em certos pontos de vista, todas as construções (independentemente da cidade, etc.) são para ser filtrados de acordo com critérios diferentes, por exemplo, other_criterion.

Problema / preocupação:

Em uma visão city_detail, eu teria de varrer todos os edifícios do tipo "extra", que é OK e normal.

Mas não estou certo de como recuperar de forma eficiente "hospital" da cidade do edifício, que é do tipo "básico", então eu devo fazer isso para cada cidade de qualquer maneira porque exatamente um tal hospital, existe em cada cidade (isto é assegurado pelo cidade hora de criação).

Haverá no máximo uma dúzia de tipos de edifícios "básicos", dos quais cerca de metade serão apresentados o tempo todo.

Estou inclinado para escrever métodos de conveniência no modelo City, e eu enfrentar três opções:

(A1) Via try e índice: .filter(...)[0]

(A2) Via try e .get(...)

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

Mas nenhum deles parece elegante. Ou é uma dessas três opções boas para combinar com algum tipo de cache, como no método get_profile() do Django no modelo User? Infelizmente, eu não tenho nenhuma experiência com o cache ainda.

É nozes para usar a opção a seguir?

(B) FKs específicas no modelo City, um para cada um dos tipos básicos mais importantes

Pergunta:

qual opção faz sentido mais?
Ou é o esquema geral defeito para esse tipo de cenário?

Especialmente em relação ao desempenho DB, o que você sugere? Preciso de uma abordagem completamente diferente?

Por favor, informe! :)

Agradecemos antecipadamente!

Foi útil?

Solução

Se uma cidade não pode ter mais do que um de cada prefeitura, corpo de bombeiros, delegacia, hospital, escola, etc, então eu acho que a maneira mais simples de fazer cumprir esta é declarar cada um como um campo no modelo:

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

Se você encontrar esta "confuso" muito em seu modelo City, que você pode considerar ter um modelo CityBuildings intermediário:

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)

Em seguida, você se refere a edifícios como, por exemplo, city.buildings.fire_station

Estas são apenas sugestões ... Eu não tenho certeza se qualquer forma é mais "correta"

Outras dicas

Para quem está interessado: silly me descobriu a existência da técnica memoization, por isso vou usar alguma forma de que se aplica a (A2), envolto em tantos métodos de conveniência no modelo da cidade como eu tenho tipos de construção "básicos" .

Esta é pelo menos um pouco menos confuso do que ter FKs em duas direções e permite que o código seja mais claro sobre a separação de interesses (modelagem de um lado, o desempenho do outro).

No rápida, fiz dois projetos para olhar para aprender e, possivelmente, emprestando material ou aplicar diretamente:

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

Mayhaps alguém vai encontrar este útil também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top