Почему обозначение столбца первичного ключа таблицы «Ид» считается плохой практикой? [закрыто]

Мой преподаватель t-sql сказал нам, что обозначение нашей колонки PK «Id» считается плохой практикой без каких-либо дальнейших объяснений.

Почему имя столбца таблицы PK «Id» считается плохой практикой?

198 голосов | спросил 2 revs, 2 users 100%
Jean-Philippe Le
1 Jam1000000amThu, 01 Jan 1970 03:00:00 +030070 1970, 03:00:00

19 ответов


234

Я собираюсь выйти и сказать это: это не очень плохая практика (и даже если это так, ее не , что плохой).

Вы можете сделать аргумент (как указано Чад ), что он может маскировать ошибки, как в следующем запросе

SELECT *
    ОТ автомобилей автомобиль
    JOIN производитель mfg
        ON mfg.Id = car.ManufacturerId
    Модели моделей JOIN
        ON mod.Id = car.ModelId
    ПРИСОЕДИНЯЙТЕ цвета col
        ON mfg.Id = car.ColorId

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

SELECT *
    ОТ автомобилей
    JOIN производитель
        ON manufacturer.Id = cars.ManufacturerId
    Модели JOIN
        ON models.Id = cars.ModelId
    ЦВЕТНЫЕ ЦВЕТА
        ON manufacturer.Id = cars.ColorId

Практика ВСЕГДА с использованием аббревиатур 3 буквы кажется мне намного хуже, чем использование имени столбца id. (Пример: кто на самом деле сократит название таблицы cars с помощью сокращения car? В чем это заканчивается?)

Точка: быть последовательной. Если ваша компания использует Id, и вы обычно делаете ошибку выше, то получите привычку использовать полные имена таблиц. Если ваша компания запрещает колонку «Идентификатор», сделайте шаг вперед и используйте любое соглашение об именах, которое они предпочитают.

Сосредоточьтесь на изучении вещей, которые являются НАРУШЕННЫМИ плохими практиками (такими как множественные вложенные коррелированные подзапросы), а не обдумывают такие проблемы. Проблема присвоения имен столбцам «ID» ближе к вопросу о вкусе, чем к плохой практике.


ПРИМЕЧАНИЕ ДЛЯ РЕДАКТОРОВ: ошибка в этом запросе намеренно и используется для создания точки. Перед редактированием прочитайте полный ответ.

ответил Peter Green 6 Mayam18 2018, 03:50:05
118

Потому что, когда у вас есть таблица с внешним ключом, вы не можете назвать этот внешний ключ «Id». У вас есть имя таблицы it TableId

И тогда ваше соединение выглядит как

SELECT * FROM cars c JOIN производитель m ON m.Id = c.ManufacturerId

И в идеале ваше состояние должно иметь одинаковое имя поля с каждой стороны

SELECT * FROM cars c JOIN производитель m ON m.ManufacturerId = c.ManufacturerId

Таким образом, хотя кажется излишним назвать Id как ManufacturerId, это делает менее вероятным, что у вас есть ошибки в ваших условиях соединения, поскольку ошибки становятся очевидными.

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

SELECT *
    ОТ автомобилей автомобиль
    JOIN производитель mfg
        ON mfg.Id = car.ManufacturerId
    Модели моделей JOIN
        ON mod.Id = car.ModelId
    ПРИСОЕДИНЯЙТЕ цвета col
        ON mfg.Id = car.ColorId

В то время как при правильном наименовании ошибка торчит ...

SELECT *
    ОТ автомобилей автомобиль
    JOIN производитель mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    Модели моделей JOIN
        ON mod.ModelId = car.ModelId
    ПРИСОЕДИНЯЙТЕ цвета col
        ON mfg.ManufacturerId = car.ColorId

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

SELECT manufacturer.Id as 'ManufacturerId'
        , cars.Id как 'CarId'
        --и т.д
    ОТ автомобилей
    JOIN производитель
        ON manufacturer.Id = cars.Id

С точными именами это не проблема

ответил Peter Green 6 Mayam18 2018, 03:50:05
60

Библиотека ActiveRecord Ruby и GORM Groovy используют «id» для суррогатного ключа по умолчанию. Мне нравится эта практика. Дублирование имени таблицы в каждом имени столбца является избыточным, утомительным для записи и более утомительным для чтения.

ответил Peter Green 6 Mayam18 2018, 03:50:05
39

Общие или ключевые имена столбцов, такие как «Имя» или «Идентификатор», должны иметь префикс с именем таблицы.

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

Менее используемый или аудиторский столбец или не-ключ (например, LastUpdatedDateTime) не имеет значения

ответил Peter Green 6 Mayam18 2018, 03:50:05
25

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

Поверьте, в течение нескольких месяцев я целый день работал в большом количестве больших баз данных (Salesforce), и самое лучшее, что я могу сказать о схемах, состоит в том, что каждая таблица имеет первичный ключ с именем Id. Я могу заверить вас, что я абсолютно не смущаюсь о присоединении первичного ключа к внешнему ключу, потому что PK называется Id. Другое дело, что люди не упомянули, что таблицы могут иметь длинные глупые имена, такие как Table_ThatDoesGood_stuff__c; это имя плохое, потому что у архитектора было похмелье утром, он придумал эту таблицу, но теперь вы говорите мне, что плохой практикой не вызывать первичный ключ Table_ThatDoesGood_stuff__cId (помня, что имена столбцов SQL aren 't в общем случае чувствительны).

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

ответил Peter Green 6 Mayam18 2018, 03:50:05
23

Я не считаю это плохой практикой. Консистенция - это король, как обычно.

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

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

Таким же образом класс Java под названием «Foo» не имеет своих свойств с префиксом «Foo», не чувствуйте себя обязанным префиксять ваши идентификаторы таблиц именами таблиц. Обычно в контексте указывается , к которому относится идентификатор.

ответил Peter Green 6 Mayam18 2018, 03:50:05
22

Из data.stackexchange.com

Id in Posts

BOOM, вопрос ответил.
Теперь скажите своему учителю, что SO плохо работает с базой данных.

ответил Peter Green 6 Mayam18 2018, 03:50:05
15

Это затрудняет (и запутывает) выполнение естественного соединения на столе, поэтому да, это плохо, если не очень плохо.

Natural Join - это древний артефакт SQL Lore (т. е. реляционная алгебра), возможно, вы видели один из них: â <в книге базы данных, возможно. То, что я имею в виду, это Natrual Join - это не новая фальсифицированная идея SQL, хотя на самом деле для СУБД ей потребовалось навсегда, поэтому для вас это не новая идея, она может быть необоснованной для вас игнорировать его существование в наши дни.

Хорошо, если вы назовете все ID вашего первичного ключа, вы потеряете легкость и простоту естественного соединения. выберите * from dudes natural join cars нужно будет написать select * from dudes inner join cars where cars.dudeid = dudes.id или select * from dudes internal присоединяйтесь к автомобилям, где dudes.carid = cars.id. Если вы можете сделать естественное соединение, вы можете игнорировать то, что на самом деле является отношением, которое, я считаю, довольно удивительно.

ответил Peter Green 6 Mayam18 2018, 03:50:05
15

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

Например, если у вас есть fooTable с столбцом fooTableId и barTable с внешним ключом fooTableId), тогда ваш запросы могут быть построены как таковые:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

Он не только сохраняет типизацию, но гораздо читабельнее по сравнению с альтернативой:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)
ответил Peter Green 6 Mayam18 2018, 03:50:05
10

Почему бы просто не спросить своего учителя?

Подумайте об этом, когда все ваши столбцы PK-таблиц называются ID, это делает их как внешние ключи кошмаром.

Имена столбцов должны быть семантически значимыми. ID относится к родовому.

ответил Peter Green 6 Mayam18 2018, 03:50:05
6

Идентификатор плохой по следующим причинам:

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

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

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

ответил Peter Green 6 Mayam18 2018, 03:50:05
5

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

И вот почему использование id - это плохая практика: id часто не является информацией только для автоматического увеличения.

рассмотрим следующие таблицы:

PK id | Countryid | Имя страны
    1 | 840 | Соединенные Штаты
    2 | 528 | Нидерланды

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

PK Countryid | Имя страны
           840 | Соединенные Штаты
           528 | Нидерланды

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

ответил Peter Green 6 Mayam18 2018, 03:50:05
4

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

Однако для меня ключевое преимущество реализует программист по обслуживанию, в частности тот, кто не был вовлечен в первоначальную разработку. Если вы использовали имя «PersonID» для идентификатора в таблице Person и последовательно использовали это имя в качестве внешнего ключа, тривиально написать запрос к схеме, чтобы узнать, какие таблицы имеют идентификатор PersonID без необходимости делать вывод, что «PersonID» это имя, используемое, когда оно является внешним ключом. Помните, что правильно или неправильно отношения внешнего ключа не всегда соблюдаются во всех проектах.

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

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

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

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

ответил Peter Green 6 Mayam18 2018, 03:50:05
4

Я всегда использую 'id' в качестве основного имени столбца для каждой таблицы просто потому, что это соглашение используемых мной фреймворков (Ruby on Rails, CakePHP), поэтому мне не нужно переопределять его все время.

Это не изменит академические причины для меня.

ответил Peter Green 6 Mayam18 2018, 03:50:05
2

Я не думаю, что это плохая практика, если она используется правильно. Обычно используется поле с автоматической добавочной идентификацией с именем «ID», которое вам никогда не нужно касаться, и используйте более дружественный идентификатор для приложения. Это может быть немного громоздкой для написания кода типа из таблицы A внутренней таблицы joinB b на a.id = b.a_id, но этот код можно убрать.

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

ответил Peter Green 6 Mayam18 2018, 03:50:05
2

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

Надеюсь, что никто не разрабатывает базу данных sql, где ID является зарезервированным словом.

CREATE TABLE CAR (ID);

Учет имени поля, первичного ключа и автоматического увеличения на 1, начиная с 1 всего в одном симпатичном маленьком 2-символьном пакете. О, и я бы назвал его CARS, но если мы собираемся сэкономить на нажатиях клавиш и кто действительно думает, что таблица под названием CAR будет иметь только один?

ответил Peter Green 6 Mayam18 2018, 03:50:05
2

Этот вопрос был избит снова и снова, но я думал, что я тоже добавлю свое мнение.

  1. Я использую id для обозначения того, что это идентификатор для каждой таблицы, поэтому, когда я присоединяюсь к таблице, и мне нужен первичный ключ, я автоматически присоединяюсь к первичному ключу.

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

  3. Для внешних ключей я использую tablenameid (опять-таки вопрос стиля), но первичный ключ, к которому я присоединяюсь, является полем id таблицы, поэтому последовательность означает, что я всегда могу легко проверять запросы

  4. id короткий и сладкий тоже

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

ответил Peter Green 6 Mayam18 2018, 03:50:05
1

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

Например, вам не удастся загрузить вашу схему в инструмент, такой как Visio, и заставить его создавать точные ERD.

ответил Peter Green 6 Mayam18 2018, 03:50:05
1

Я считаю, что люди здесь охватывают практически все аспекты, но я хочу добавить, что «id» не является и не должен быть прочитан как «идентификатор», это скорее «индекс», и, конечно же, он не указывает или не описывает идентификатор строки , (Возможно, я использовал неправильную формулировку, пожалуйста, поправьте меня, если я это сделал)

Это более или менее то, как люди читают данные таблицы и как они пишут свой код. Я лично и, скорее всего, это самый популярный способ, который я вижу чаще всего, - это то, что кодеры записывают полную ссылку как table.id, даже если им не нужно делать объединения или /и объединения. Например:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>

Таким образом, вы можете перевести его на английский как «Дайте мне цвет и модель того автомобиля, который пронумерован как». а не как «Дайте мне цвет и модель этого автомобиля, который обозначается как номер». Идентификатор никак не отражает автомобиль, это только индекс автомобиля, серийный номер, если хотите. Так же, как если вы хотите взять третий элемент из массива.

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

Хотя, есть случаи, когда это не используется, например (гораздо более редкий пример), когда идентификатор представляет собой строку, которая действительно описывает. Например id = "RedFordMustang1970" или что-то подобное. Я действительно надеюсь, что смогу объяснить это, по крайней мере, чтобы получить эту идею.

ответил Peter Green 6 Mayam18 2018, 03:50:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132