Зачем указывать атрибуты первичного/внешнего ключа в именах столбцов

StackOverflow https://stackoverflow.com/questions/214045

Вопрос

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

select t1.col_a, t1.col_b, t2.col_z
from t1 inner join t2 on t1.id_foo_pk = t2.id_foo_fk

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

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

select t1.col_a, t1.col_b, t2.col_z
from t1 inner join t2 on t1.id_foo = t2.id_foo

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

tx inner join ty on tx.id_bar = ty.id_bar

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

Какая проблема здесь решается?(Я знаю, что это приглашение к обсуждению, и не стесняйтесь это делать.Но в то же время я являюсь ищу ответ, возможно, я действительно что-то упускаю).

Это было полезно?

Решение

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

SELECT * FROM foo JOIN bar USING (foo_id);

Ключевое слово USING предполагает, что в обеих таблицах существует столбец с одинаковым именем и что вам нужно равное соединение.Приятно иметь это в качестве сокращения для более подробного описания:

SELECT * FROM foo JOIN bar ON (foo.foo_id = bar.foo_id);

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

CREATE TABLE Employees (
  emp_id INT PRIMARY KEY,
  manager_id INT REFERENCES Employees(emp_id)
);

Также таблица может иметь несколько внешних ключей к одной и той же родительской таблице.Полезно использовать имя столбца для описания характера связи:

CREATE TABLE Bugs (
  ...
  reported_by INT REFERENCES Accounts(account_id),
  assigned_to INT REFERENCES Accounts(account_id),
  ...
);

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

Другие советы

Я согласен с вами.Размещение этой информации в имени столбца попахивает дурацким идиотизмом венгерской нотации первых дней Windows.

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

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

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

Игнорируя составные первичные ключи, я не понимаю, почему простого «id» недостаточно для первичного ключа и «_id» для внешних ключей.

Таким образом, типичное условие соединения становится customer.id = order.customer_id.

Если существует более одной ассоциации между двумя таблицами, я был бы склонен использовать ассоциацию, а не имя таблицы, поэтому, возможно, «parent_id» и «child_id», а не «parent_person_id» и т. д.

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

Я использовал «fk_» в начале любых внешних ключей таблицы главным образом потому, что это помогало мне сохранять ясность при разработке БД для проекта в моем магазине.Поскольку я раньше не занимался никакой работой с БД, это мне помогло.Оглядываясь назад, возможно, мне и не нужно было этого делать, но к названиям некоторых столбцов было добавлено три символа, так что я не переживал.

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

Удачи!

Я согласен с вами — я использую другой подход, который я видел рекомендованным во многих корпоративных средах:

Назовите столбцы в формате ИмяТаблицыИмяПоля, поэтому, если бы у меня была таблица Customer и UserName было одним из моих полей, это поле называлось бы CustomerUserName.Это означает, что если бы у меня была другая таблица под названием Invoice, а имя пользователя клиента было внешним ключом, я бы назвал ее InvoiceCustomerUserName, а когда я ссылаюсь на нее, я бы назвал ее Invoice.CustomerUserName, что сразу же сообщает мне, в какой таблице она находится.

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

Я использую только FK_ и PK_ в АКТУАЛЬНЫХ именах внешнего и первичного ключей в СУБД.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top