Django DB Design - Ведение общих и исторических данных - PullRequest
4 голосов
/ 12 апреля 2011

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

У нас есть небольшое приложение Django для управления ежегодной конференцией.

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

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

Например, у каждого AccomodationRoom есть имя, здание и особенности, которые будут встречаться из года в год.Однако другие вещи, такие как фактическая доступность кроватей, будут меняться из года в год.

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

Мой первоначальный подход состоял в том, чтобы просто создать AccommodationodationRoom, в котором хранятся общие данные, а затем, например,Доступность BedAvailable, которая хранила временную информацию из года в год, а также давала ссылку на ежегодную конференцию.Например:

class AccommodationRoom(models.Model):
    name = models.CharField(max_length=50)
    site = models.ForeignKey(Site)
    features = models.ManyToManyField(AccommodationFeature, null=True, blank=True)

class BedAvailability(models.Model):
    number_of_single_beds = models.IntegerField()
    number_of_double_beds = models.IntegerField()
    conference = models.ForeignKey(Conference)
    accommodation_room = models.ForeignKey(AccommodationRoom)

class Conference(models.Model):
    year = models.CharField(max_length=4) # Example

Однако другим способом было бы просто покончить с этими двумя моделями и иметь единую модель AccommodationodationRoom, в которой содержалось все, связать это непосредственно с моделью Конференции и затем обеспечить уникальностьна AccommodationodationRoom.name и AccommodationodationRoom.Conference.

class AccommodationRoom(models.Model):
    name = models.CharField(max_length=50)
    site = models.ForeignKey(Site)
    features = models.ManyToManyField(AccommodationFeature, null=True, blank=True)
    conference = models.ForeignKey(Conference)
    number_of_single_beds = models.IntegerField()
    number_of_double_beds = models.IntegerField()

    class Meta:
        ordering = ['conference', 'name']
        unique_together = (("name", "conference"),)

Или, может быть, есть лучший способ сделать это, о котором я даже не думал?Открыты для предложений здесь.

Ура, Виктор

1 Ответ

1 голос
/ 19 февраля 2013

Небольшая модификация вашего первого решения (я думаю, что это лучшее решение, потому что оно более нормализовано, чем второе)

class AccommodationRoom(models.Model):
    name = models.CharField(max_length=50)
    site = models.ForeignKey(Site)
    features = models.ManyToManyField(AccommodationFeature, null=True, blank=True)
    bed_availability = models.ForeignKey(BedAvailability)

class BedAvailability(models.Model):
    number_of_single_beds = models.IntegerField()
    number_of_double_beds = models.IntegerField()

class Conference(models.Model):
    year = models.CharField(max_length=4) # Example
    accommodation = models.ForeignKey(AccommodationRoom)

Используя административный сервер Django, вы можете сначала создать объект BedAvailability со спецификацией кроватей. Затем вы можете создать объект AccommodationodationRoom и связать с ним объект BedAvailability. Затем вы можете, наконец, создать объект Conference и связать с ним объект AccommodationRoom.

Если вам понадобится новый набор BedAvailability для того же AccommodationRoom на другой год, вы можете создать новый объект BedAvailability с новыми спецификациями и связать его с AccommodationRoom. Вам не нужно будет повторно вводить данные AccommodationRoom для следующей конференции, даже если технические характеристики BedAvailability изменятся.

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