Почему люди не рекомендуют использовать имя «Ид» для столбца идентификации?

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

Я видел, что люди предлагают префикс Id с именем таблицы, но это, похоже, делает больше работы для человека, записывающего SQL-запросы (или программиста, если вы используете ORM, например Entity Framework), особенно в отношении более длинных имен таблиц, таких как CustomerProductId или AgencyGroupAssignementId

Один сторонний поставщик, которого мы наняли для создания чего-то для нас, на самом деле назвал все свои столбцы идентификации Ident, чтобы избежать использования Id. Сначала я думал, что они это сделали, потому что Id было ключевым словом, но когда я просмотрел его, я обнаружил, что Id не является ключевым словом в SQL Server 2005, что что мы используем.

Итак, почему люди не рекомендуют использовать имя Id для столбца идентификации?

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

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

63 голоса | спросил Rachel 17 PMpTue, 17 Apr 2012 17:33:15 +040033Tuesday 2012, 17:33:15

10 ответов


22

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

  • Меньше ошибок, поскольку поля идентичности не называются одинаковыми

    Вы не можете ошибочно написать запрос, который присоединяется к B.Id = B.Id вместо A.Id = B.Id, потому что поля идентичности никогда не будут назвал то же самое.

  • Более четкие имена столбцов.

    Если вы посмотрите на столбец с именем CustomerId, вы сразу же узнаете, какие данные находятся в этом столбце. Если имя столбца было чем-то общим, например Id, вам также нужно знать имя таблицы, чтобы узнать, какие данные содержит столбец.

  • Избегает ненужных псевдонимов столбцов

    Теперь вы можете написать SELECT CustomerId, ProductId из запроса, который присоединяется к Customers с помощью Products, а не SELECT Customer.Id as CustomerId, Products.Id as ProductId

  • Разрешает синтаксис JOIN..USING

    Вы можете присоединиться к таблицам с синтаксисом Customer JOIN Products USING (CustomerId) вместо Customer JOIN Products ON Customer.Id = Products.Id

  • Ключ легче найти в поиске

    Если вы ищете поле идентификации клиента в большом решении, поиск CustomerId гораздо полезнее поиска Id

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

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

ответил Rachel 18 PMpWed, 18 Apr 2012 21:13:53 +040013Wednesday 2012, 21:13:53
42

Префикс имени таблицы имеет очень веские причины.

Рассмотрим:

TableA (id int identity, stringdata varchar(max))

TableB (id int identity, stringdata varchar(max))

Мы хотим DELETE из записей TableA, которые существуют в обеих таблицах. Достаточно просто, мы просто сделаем INNER JOIN:

DELETE a
FROM 
  TableA A
INNER JOIN 
  TableB B
    ON b.id = B.id

.... , и мы просто уничтожили все TableA. . Мы случайно сравнили ID B с самим собой - каждая запись соответствовала, и каждая запись удалялась.

Если поля были названы TableAId и TableBId, это было бы невозможно (Invalid field name TableAid in TableB).

Лично у меня нет проблем с использованием имени id в таблице, но лучше использовать предисловие к имени таблицы (или имени объекта, если TableA были люди, а затем PeopleId тоже работали нормально), чтобы избежать случайного сравнения с неправильным полем и вдуванием чего-то.

Это также делает его очень очевидным, когда поля исходят из длинных запросов с большим количеством JOIN s.

ответил JNK 17 PMpTue, 17 Apr 2012 17:41:21 +040041Tuesday 2012, 17:41:21
34

В основном, чтобы внешние ключи не становились огромной болью. Допустим, у вас две таблицы: Customer и CustomerAddress. Первичный ключ для обоих - столбец с именем id, который является столбцом identity (int).

Теперь вам нужно указать идентификатор клиента, указанный в CustomerAddress. Очевидно, вы не можете назвать идентификатор столбца, так что вы идете с customer_id.

Это приводит к нескольким проблемам. Во-первых, вы должны постоянно помнить, когда нужно вызвать столбец «id», а когда называть его «customer_id». И если вы это испортите, это приведет к второй проблеме. Если у вас большой запрос с дюжиной или около того, и он не возвращает никаких данных, получайте удовольствие от игры Where's Waldo и поискать эту опечатку:

ON c.id = ca.id

Упс, должен был быть ON c.id = ca.customer_id. Или еще лучше, назовите свои столбцы идентификационной информации, так что это может быть ON c.customer_id = ca.customer_id. Затем, если вы случайно используете неправильный псевдоним таблицы, customer_id не будет столбцом в этой таблице, и вы получите хорошую ошибку компиляции, а не пустые результаты и последующее кодовое косоглазие.

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

ответил db2 17 PMpTue, 17 Apr 2012 22:11:46 +040011Tuesday 2012, 22:11:46
10

Чтобы скопировать мой ответ из связанного вопроса:

Существует ситуация, когда придерживаться «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)
ответил Izkata 17 PMpTue, 17 Apr 2012 20:55:42 +040055Tuesday 2012, 20:55:42
7

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

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

| Author_Nickname | Author_Email | Post_Title | Post_Body |
+-----------------+--------------+------------+-----------+
| dave            | [email protected]   | Blah       | Bla bla   |
| dave            | [email protected]   | Stuff      | I like    |
| sophie          | [email protected]     | Lorem      | Ipsum     |

При нормализации это приведет к двум таблицам:

Автор:

| Author_Nickname | Author_Email |
+-----------------+--------------+
| dave            | [email protected]   |
| sophie          | [email protected]     |

Сообщение

| Author_Nickname | Post_Title | Post_Body |
+-----------------+------------+-----------+
| dave            | Blah       | Bla bla   |
| dave            | Stuff      | I like    |
| sophie          | Lorem      | Ipsum     |

Здесь Author_Nickname будет основным ключом для таблицы автора и внешним ключом в таблице сообщений. Даже если Author_Nickname отображается в двух таблицах, оно все равно соответствует единице информации, т. Е. каждое имя столбца соответствует одному полю .

Во многих случаях не может быть уникального ограничения для исходных полей, поэтому вместо этого вместо этого используется числовое искусственное поле. Это не меняет того факта, что каждое имя столбца по-прежнему представляет собой одно поле. В традиционном дизайне базы данных имена отдельных столбцов соответствуют одиночным полям, даже если они не являются ключами. (например, можно использовать part.partname и client.clientname , а не part.name и client.name ). Это является причиной существования INNER JOIN ... USING <key> и синтаксиса NATURAL JOIN.

Однако в настоящее время и с ORM-уровнями, легко доступными на многих языках, базы данных часто разрабатываются как уровень защиты для языков OO, в которых естественно, что переменные, которые имеют одинаковую роль в разных классах, называются одинаковыми ( part.name и client.name , а не part.partname и client.clientname ). В этом контексте я использую «ID» для своих первичных ключей.

ответил stilgar 18 AMpWed, 18 Apr 2012 00:16:57 +040016Wednesday 2012, 00:16:57
6
  

Один сторонний поставщик, которого мы наняли для создания чего-то для нас на самом деле   назвал все свои столбцы Ident, чтобы избежать использования Id.

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

Есть хорошая статья о условных обозначениях SQL на сайте Drupal , которая указывает на хорошую практику для этой ситуации:

  

Хорошей практикой является префикс имен таблиц с именем модуля   предотвращать возможные конфликты пространства имен.

С этой точки зрения, CustomerProductId и AgencyGroupAssignmentId имеют смысл использовать. Да, это довольно многословие. Вы могли бы сократить его, но самым большим моментом для этого является , будет ли разработчик, который следует за вами, понять, что вы имели в виду . Идентификаторы, предваряемые подробными именами таблиц, не должны оставлять двусмысленности относительно того, что они собой представляют. И (для меня) это важнее, чем сэкономить несколько нажатий клавиш.

ответил Aaron 17 PMpTue, 17 Apr 2012 17:59:04 +040059Tuesday 2012, 17:59:04
5

Я называю мои столбцы CustomerID вместо ID, поэтому всякий раз, когда я печатаю

FROM dbo.Customers AS c JOIN dbo.CustomerOrders AS o

SQL Prompt немедленно предлагает следующее

ON c.CustomerID = o.CustomerID 

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

ответил A-K 17 PMpTue, 17 Apr 2012 18:23:54 +040023Tuesday 2012, 18:23:54
4

По той же причине, почему вы не назовете все ваши поля varchar что-то вроде «UserText» и «UserText1», или почему вы не будете использовать «UserDate» и «UserDate1».

Обычно, если у вас есть поле идентификации в таблице, это ваш первичный ключ. Как бы вы построили дочернюю таблицу с внешним ключом в родительскую таблицу, если первичный ключ в обеих таблицах был id?

Не все согласны с этой методологией, но в моих базах данных я назначаю уникальную аббревиатуру для каждой таблицы. ПК для этой таблицы будет называться PK_ [abbrv] ID. ЕСЛИ это используется как FK в любом месте, тогда я бы использовал FK_ [abbrv] ID. Теперь у меня есть нулевая работа, чтобы выяснить, что такое отношения таблицы.

ответил DForck42 17 PMpTue, 17 Apr 2012 19:16:57 +040016Tuesday 2012, 19:16:57
4

В принципе по той же причине вы обычно не называете параметры parameter1, parameter2 ... это точный, но не описательный. Если вы видите TableId, то вы, вероятно, можете смело предположить, что он используется для хранения pk для таблицы, независимо от контекста.

Что касается того, кто использовал Иден, он полностью упускает эту точку, учитывая выбор между Идентивом и Идентификатором Id. Идентификатор еще более запутан, чем Id.

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

ответил jmoreno 17 PMpTue, 17 Apr 2012 19:54:50 +040054Tuesday 2012, 19:54:50
2

Используйте префикс, чтобы одно и то же имя могло использоваться как в контексте первичного ключа, так и в контексте внешнего ключа, так что вы можете выполнять natural join /join ... using .

ответил DrPizza 18 AMpWed, 18 Apr 2012 00:35:35 +040035Wednesday 2012, 00:35:35

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

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

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