Вопрос DBA: лучший способ использовать FK - PullRequest
2 голосов
/ 14 февраля 2010

Что и когда является лучшим способом использовать FK, не получая FK «избыточность».

Допустим, у меня есть три таблицы Account, Category и Product.

1: таблица счетов

Определение:

  • Id, Первичный BigInt
  • Имя, Варчар

2: Таблица категории

Определение:

  • Id, Первичный BigInt
  • AccountId, BigInt ForeignKey
  • Имя, Varchar

3: Табличный продукт

Определение:

  • Id, Основной BigInt
  • AccountId, BigInt ForeignKey - "черная овца"
  • CategoryId, BigInt ForeignKey
  • Имя, Varchar ... и т. Д.

Мой вопрос (так как я не администратор БД): неужели плохо или глупо использовать FK AccountId для таблицы Product, когда я знаю, что мой FK CategoryId указывает на таблицу, в которой содержится тот же FK?

Я просто думаю, исходя из принципа СУХОЙ.

Почему мне интересно, скажем, я хочу получить все продукты для учетной записи x . Если у меня нет идентификатора учетной записи FK для продукта, мне всегда нужно присоединиться к таблице категорий, чтобы получить все продукты для учетной записи x . Полагаю, это может быть хитом производительности.

Если у вас есть мнение, а я имею в виду ЛЮБОЕ мнение по этому вопросу. Пожалуйста, буквально УБИВАЙТЕ эту ветку, написав свою точку зрения на то, как, по вашему мнению, следует использовать FK.

Спасибо!

Robin

Ответы [ 4 ]

1 голос
/ 14 февраля 2010

Как почти все в программировании, это "зависит".

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

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

После этого, если вы начнете кодировать свое приложение, и извлечение данных станет проблемой, вам следует приступить к созданию индексов. Если это не сработает, вы должны пойти по пути нормализации.

Моделирование вашей базы данных предложенным способом может привести к некоторым проблемам. Рассмотрим учетную запись A с категорией C:

  • Что должно произойти, если вы создадите Продукт P с этими ФК?
  • Что произойдет, если вам нужно изменить категорию продукта?
  • Вам нужно следить за историей категорий, например, "какой была категория продуктов два месяца назад"?
  • Продукт действительно «принадлежит» учетной записи? Таким образом, двум аккаунтам с одним и тем же продуктом нужно, чтобы этот продукт был добавлен дважды?
0 голосов
/ 14 февраля 2010

Ваша структура таблиц выглядит немного странно. Вы пытаетесь сохранить список продуктов, проданных для определенной учетной записи, и классифицировать эти продукты? Если так, я бы сделал это так:

Account
    ID
    Name

Category
    ID
    Name

Product
    ID
    Name
    CategoryID

AccountProduct
    ID
    AccountID
    ProductID

Последняя таблица содержит данные о продажах продуктов для учетной записи.

0 голосов
/ 14 февраля 2010

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

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

Между продуктами и учетными записями нет связи «многие ко многим», которую можно создать с помощью отдельной таблицы. На данный момент каждый продукт имеет определенную категорию и аккаунт.

Вы не можете сначала создать категорию без учетной записи и т. Д.

0 голосов
/ 14 февраля 2010

Это плохой дизайн / просто глупо использовать FK AccountId для таблицы Product, когда я знаю, что мой FK CategoryId указывает на таблицу с тем же FK?

ИМО да. Этот дизайн не находится в третьей нормальной форме из-за этого столбца, и на этом этапе нет необходимости вносить денормализацию.

Если у меня нет идентификатора учетной записи FK для продукта, мне всегда нужно присоединиться к таблице категорий, чтобы получить все продукты для учетной записи x.

Да.

Полагаю, это может быть хитом производительности.

Нет, не совсем. Базы данных предназначены именно для такого рода операций; вам должно быть вполне удобно использовать простые внутренние JOIN-соединения, подобные этим, в своих запросах.

Вам иногда требуется денормализация из соображений производительности. Но не здесь.

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