БД / производительность: макет модели django, который редко ссылается на своего родителя более одного раза - PullRequest
0 голосов
/ 30 ноября 2009

У меня есть приложение для представления вымышленных упрощенных городов.

Обратите внимание на следующие модели 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'

Пояснения по выбору этой настройки:

(1) В каждом городе есть определенные здания «базового» типа, которые встречаются ровно один раз в каждом городе (например, мэрия, пожарная часть, полицейский участок, больница, школа) и, возможно, десятки зданий «дополнительного» типа, такие как танцевальные клубы.

(2) В некоторых видах все здания (независимо от города и т. Д.) Должны фильтроваться в соответствии с различными критериями, например, other_criterion.

Проблема / беспокойство:

В представлении city_detail мне придется зацикливаться на любых зданиях типа "extra", что нормально и нормально.

Но я не уверен, как эффективно извлечь городское "больничное" здание, которое имеет "базовый" тип, поэтому я должен сделать это для каждого города в любом случае, потому что в каждом городе существует только одна такая больница (это гарантируется в время создания города).

Будет не более дюжины «базовых» типов зданий, из которых около половины будет представлено постоянно.

Я склонен писать удобные методы для модели City, и у меня есть три варианта:

(A1) Через try и индекс: .filter(...)[0]

(A2) Через try и .get(...)

(A3) Через try и .filter(...).latest()

Но ни один из них не кажется элегантным. Или один из этих трех вариантов хорошо сочетать с некоторым типом кэширования, как в методе Django get_profile() на модели User? К сожалению, у меня пока нет опыта кеширования.

Можно ли использовать следующую опцию?

(B) конкретных FK в модели City, по одному для каждого из наиболее важных базовых типов

Вопрос:

Какой вариант имеет смысл больше всего?
Или схема обычно неисправна для такого сценария?

Особенно что касается производительности БД, что вы предлагаете? Нужен ли мне совершенно другой подход?

Пожалуйста, сообщите! :)

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 30 ноября 2009

Если в городе может быть не более одного мэрии, пожарной части, полицейского участка, больницы, школы и т. Д., То я думаю, что самый простой способ добиться этого - объявить каждый из них как поле на модели:

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

Если вы считаете, что это слишком "грязно" в модели вашего города, вы можете подумать о наличии промежуточной CityBuildings модели:

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)

Тогда вы называете здания, например, city.buildings.fire_station

Это всего лишь предложения ... Я не уверен, является ли тот или иной путь более "правильным"

0 голосов
/ 02 декабря 2009

Для тех, кто заинтересован: глупо, я обнаружил существование техники запоминания, поэтому я буду использовать некоторую форму, примененную к (A2), обернутую в столько же удобных методов в модели города, сколько у меня есть «базовые» типы зданий .

Это, по меньшей мере, несколько менее беспорядочно, чем использование FK в двух направлениях, и позволяет коду более четко определять разделение интересов (моделирование с одной стороны, производительность с другой).

Вскоре я разработал два проекта для изучения и, возможно, кредитования или непосредственного обращения:

  1. django-memoize
  2. github.com / husio / Джанго-easycache /

Может кто-нибудь найдет это полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...