почему models.ForeignKey выгоден? - PullRequest
1 голос
/ 06 февраля 2012

В моих моделях у меня есть класс Concert и класс Venue.Каждое место имеет несколько концертов.Я связывал класс Concert с Venue с помощью простого

venue = models.IntegerField(max_length = 10)

..., содержащего первичный ключ объекта объекта.Коллега предложил вместо этого использовать venue = models.ForeignKey(Venue).Хотя это также работает, мне интересно, стоит ли это менять, потому что я смог разобрать все концерты для места, просто используя идентификатор места в Concert.objects.filter(venue=4) так же, как я мог бы сделать это с ForeignKey: Venue_instance.Concert_set.all().У меня никогда не было проблем с использованием моего метода.

То, как я это вижу, с использованием IntegerField и objects.filter() является таким же отношением к ManyToOne, как и ForeignKey, поэтому яхочу знать где я не прав.Почему ForeignKeys выгодно?Они быстрее?Это лучший дизайн базы данных?Код уборщика?

Ответы [ 2 ]

3 голосов
/ 06 февраля 2012

ForeignKey - это концепция базы данных , реализованная в большинстве баз данных, которая также обеспечивает ссылочную целостность .

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

Кроме обычного одностороннего связывания, Django также добавляет параметр в противоположную сторону, как вы узнали. Если у вас есть экземпляр объекта, вы можете запросить venue.concert_set.

Что меня больше всего беспокоит, так это то, что я не использую FK и не использую свое собственное число с помощью целого числа:

  • У вас нет проверки ссылочной целостности.
  • Вы теряете силу SQL. Каждый ваш запрос средней глубины теперь будет нуждаться в нескольких попаданиях в базу данных, поскольку вы не можете присоединиться. - Вы также теряете все рычаги, которые предоставляет инфраструктура для работы с SQL
3 голосов
/ 06 февраля 2012

Я бы сказал, что наиболее практичным преимуществом внешнего ключа является возможность автоматически запрашивать отношения. Django генерирует соединения автоматически.

Как вы уже упоминали, помощники автоматического обратного отношения тоже хороши.

Вот несколько примеров, которые были бы более сложными только с целочисленными отношениями.

concerts = Concert.objects.filter(...)

concerts.order_by('venue__attribute') # ordering beyond PK.
concerts.filter(venue__name='foo') # filter by a value across the relationship
concerts.values_list('venue__name') # get just venue names
concerts.values('venue__city').annotate() # get unique values across the venue

concerts.filter(venue__more__relationships='foo')

Venue.objects.filter(concert__name='Coachella') # reverse lookups work too

# with an integer field for Concert.venue, you'd have to do something like...
Venue.objects.filter(id__in=Concert.objects.filter(name='Coachella')) 

Как уже отмечали другие ... целостность базы данных полезна, каскадное удаление (настраиваемое, конечно) и facepalm мне только что пришло в голову, что администратор django и фреймворк форм прекрасно работают с внешними ключами.

class ConcertInline(admin.TabularInline):
    model = Concert

class VenueAdmin(admin.ModelAdmin):
    inlines = [ConcertInline]
    # that was quick!

Я уверен, что есть и другие примеры функций django, обрабатывающих внешние ключи.

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