Подтвердить что ты не робот

Нужны ли в таблицах ссылок бессмысленное поле первичного ключа?

Я работаю над несколькими таблицами ссылок, и я подумал (Danger Will Robinson, Danger), каковы возможные структуры таблицы ссылок и каковы их про и con.

Я придумал несколько возможных ограничений для таблицы ссылок:

Традиционная модель с тремя колонками

  • id - автоматический номер PRIMARY
  • table1fk - внешний ключ
  • table2fk - внешний ключ

Это классика, в большинстве книг, - сказал Нуфф.

Индексированная 3-х столбчатая модель

  • id - автоматический номер PRIMARY
  • table1fk - внешний ключ INDEX ('table1fk')
  • table2fk - внешний ключ INDEX ('table2fk')

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

Составной ключ 2 столбца ADD PRIMARY KEY ('table1fk' , 'table2fk')

  • table1fk - внешний ключ
  • table2fk - внешний ключ

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

Возможны ли какие-либо потенциальные проблемы с опцией составного ключа 2 столбца? Есть ли проблема с индексацией, которая может возникнуть? Выиграла производительность? Все, что могло бы дисквалифицировать это как возможный вариант?

4b9b3361

Ответ 1

Для настоящих таблиц ссылок они обычно не существуют как объектные объекты в моих объектных моделях. Таким образом, суррогатный ключ никогда не используется. Съемный элемент из коллекции приводит к удалению элемента из отношения ссылки, где известны оба внешних ключа (Person.Siblings.Remove(Sibling) или Person.RemoveSibling(Sibling), которые соответствующим образом переведены на уровне доступа к данным как usp_Person_RemoveSibling(PersonID, SiblingID)).

Как отметил Майк, если он станет фактическим объектом в вашей объектной модели, тогда он может заслуживать идентификатор. Однако даже с добавлением временных факторов, таких как эффективные начальные и конечные даты отношений и т.д., Это не всегда ясно. Например, сбор может иметь эффективную дату, связанную с совокупным уровнем, поэтому сама связь все еще не может стать объектом с любыми открытыми свойствами.

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

Ответ 2

Я бы использовал составной ключ и лишний бессмысленный ключ.

Я бы не использовал систему ORM, которая применяет такие правила для моей структуры db.

Ответ 3

Если это настоящая таблица соединений "много-ко-многим", то дамп ненужного столбца id (если ваш ORM не требует этого, в этом случае вам нужно решить, будет ли ваш интеллект превзойти вашу практичность).

Но я считаю, что истинные таблицы соединений довольно редки. Обычно это не так давно, прежде чем я захочу поместить некоторые другие данные в эту таблицу. Из-за этого я почти всегда моделирую эти таблицы соединений как объекты с самого начала и вставляю там идентификатор.

Ответ 4

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

Ответ 5

Композитный ПК и отключите кластеризацию.

Ответ 6

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

Ответ 7

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

Я согласен, что не индексирование внешних ключей - это плохая идея в зависимости от того, как вы идете.

Ответ 8

Если вы используете ORM для получения/изменения данных, для некоторых из них требуется первичный ключ с одним столбцом (спасибо Tom H за указание на это) для правильной работы (я считаю, что Subsonic 2.x был таким образом, не уверен в 3.x).

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

Ответ 9

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

Ответ 10

Если вам нужно пройти таблицу соединений "в обоих направлениях", которая начинается только с ключа table1fk или только таблицы table2fk, вы можете добавить второй, обратный составной индекс.

ADD KEY ('table2fk', 'table1fk')

Ответ 11

Правильный ответ:

  • Первичный ключ ('table1fk' , 'table2fk')
  • Еще один индекс на ('table2fk' , 'table1fk')

Потому что:

  • Вам не нужен индекс только для table1fk или table2fk: оптимизатор будет использовать PK
  • Скорее всего, вы будете использовать таблицу "оба" пути
  • Добавление суррогатного ключа требуется только из-за ORM braindead

Ответ 12

Есть что-то называемое идентификацией и неидентификацией. При идентификации отношений FK является частью PK во многих таблицах. Например, скажем, что у нас есть таблицы Person, Company и таблица many-to-many Employment. В идентифицирующей связи оба fk PersonID и CompanyID являются частью pk, поэтому мы не можем повторять комбинацию PersonID, CompanyID.

TABLE Employment(PersonID int (PK,FK), CompanyID int (PK,FK))

Теперь предположим, что мы хотим захватить историю занятости, поэтому человек может покинуть компанию, работать где-то в другом месте и позже вернуться в ту же компанию. Здесь связь не идентифицируется, теперь комбинация PersonID, CompanyID может повторяться, поэтому таблица будет выглядеть примерно так:

TABLE Employment(EmploymentID int (PK), PersonID int (FK), CompanyID int (FK), 
                     FromDate datetime, ToDate datetime)