Наименование столбцов идентификаторов в таблицах базы данных - PullRequest
86 голосов
/ 16 октября 2008

Мне было интересно узнать мнение людей о присвоении имен столбцам ID в таблицах базы данных.

Если бы у меня была таблица с именем «Счета-фактуры» с первичным ключом столбца идентификаторов, я бы назвал этот столбец «InvoiceID», чтобы не конфликтовать с другими таблицами, и очевидно, что это.

Там, где я работаю, они называют все идентификаторы столбцов ID.

Таким образом, они будут делать следующее:

Select  
    i.ID 
,   il.ID 
From
    Invoices i
    Left Join InvoiceLines il
        on i.ID = il.InvoiceID

Теперь я вижу здесь несколько проблем:
1. Вам нужно будет создать псевдоним столбцов на
. 2. ID = InvoiceID не вписывается в мой мозг
3. Если вы не указали псевдоним таблиц и сослались на InvoiceID, очевидно ли, в какой таблице он находится?

Что думают другие люди на эту тему?

Ответы [ 24 ]

132 голосов
/ 16 октября 2008

Я всегда предпочитал ID для TableName + ID для столбца id, а затем TableName + ID для внешнего ключа. Таким образом, все таблицы имеют одинаковое имя для поля id, и нет избыточного описания. Это кажется мне более простым, потому что все таблицы имеют одинаковое имя поля первичного ключа.

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

45 голосов
/ 16 октября 2008

В моей компании в последнее время произошла ссора по поводу этой вещи. Появление LINQ сделало избыточный шаблон tablename + ID еще более очевидно глупым в моих глазах. Я думаю, что самые разумные люди скажут, что если вы пишете свой SQL таким образом, что вам нужно указывать имена таблиц, чтобы различать FKs , то это не только экономия при наборе текста, но это добавляет ясности к вашему SQL, чтобы использовать только идентификатор, в котором вы можете четко видеть, какой PK , а какой FK .

1011 * Е.Г. *

ОТ сотрудников e ЛЕВЫЕ СОЕДИНЕНИЯ Клиенты c ON e.ID = c.EmployeeID

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

29 голосов
/ 16 октября 2008

Мы используем InvoiceID, а не ID. Это делает запросы более читабельными - когда вы видите только ID, это может означать что угодно, особенно когда вы называете таблицу i.

20 голосов
/ 21 сентября 2011

ID - это антипаттерн SQL. Смотри http://www.amazon.com/s/ref=nb_sb_ss_i_1_5?url=search-alias%3Dstripbooks&field-keywords=sql+antipatterns&sprefix=sql+a

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

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

Если вы хотите использовать синтаксис USING, который допускают некоторые базы данных, вы не сможете использовать ID.

Если вы используете ID, вы можете легко получить ошибочное соединение, если вам случится копировать синтаксис соединения (не говорите мне, что никто никогда этого не делает!) И забыть изменить псевдоним в условии соединения.

Итак, теперь у вас есть

select t1.field1, t2.field2, t3.field3
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t1.id = t3.table2id

когда вы имели в виду

select t1.field1, t2.field2, t3.field3 
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t2.id = t3.table2id

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

20 голосов
/ 07 июня 2012

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

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

В моей текущей позиции мы используем структуру сущностей, используя генерацию POCO. Используя стандартное соглашение об именовании Id, PK позволяет наследовать базовый класс poco с проверкой и тому подобное для таблиц, которые имеют набор общих имен столбцов. Использование Tablename + Id в качестве PK для каждой из этих таблиц уничтожает возможность использовать базовый класс для них.

Просто пища для размышлений.

10 голосов
/ 21 сентября 2011

Мои предпочтения также ID для первичного ключа и TableNameID для внешнего ключа. Мне также нравится иметь столбец «имя» в большинстве таблиц, где я храню читаемый пользователем идентификатор (т.е. имя :-)) записи. Эта структура предлагает большую гибкость в самом приложении, я могу обрабатывать таблицы таким же образом. Это очень мощная вещь. Обычно программное обеспечение OO строится поверх базы данных, но набор инструментов OO не может быть применен, потому что сама база данных не позволяет этого. Иметь столбцы id и name все еще не очень хорошо, но это шаг.

Выберите
i.ID, il.ID От Счета я Осталось присоединиться к InvoiceLines il на i.ID = il.InvoiceID

Почему я не могу это сделать?

Select  
    Invoices.ID 
,   InvoiceLines.ID 
From
    Invoices
    Left Join InvoiceLines
        on Invoices.ID = InvoiceLines.InvoiceID

На мой взгляд, это очень легко читаемо и просто. Называть переменные как i и il - плохой выбор.

10 голосов
/ 16 октября 2008

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

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

7 голосов
/ 17 ноября 2010

Я только начал работать в месте, где используется только «ID» (в основных таблицах, на которые ссылается TableNameID во внешних ключах), и уже обнаружил ДВУХ производственных проблем, непосредственно вызванных этим.

В одном случае запрос использовал «... где ID в (SELECT ID FROM OtherTable ...» вместо «... где ID в (SELECT TransID FROM OtherTable ...».

Может ли кто-нибудь честно сказать, что было бы намного легче обнаружить, если бы использовались полные, непротиворечивые имена, где неправильный оператор читал бы «... где TransID in (SELECT OtherTableID from OtherTable ...»? не думаю.

Другая проблема возникает при рефакторинге кода. Если вы используете временную таблицу, тогда как ранее запрос вышел из основной таблицы, тогда старый код читает «... dbo.MyFunction (t.ID) ...», и если это не изменилось, то «t» теперь относится к временная таблица вместо основной таблицы, вы даже не получите ошибку - просто ошибочные результаты.

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

6 голосов
/ 16 октября 2008

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

4 голосов
/ 15 августа 2013

I лично предпочитают (как было указано выше) Table.ID для PK и TableID для FK . Даже (пожалуйста, не стреляйте в меня) Microsoft Access рекомендует это.

ОДНАКО, я ТАКЖЕ знаю, что некоторые инструменты генерации предпочитают TableID для PK, потому что они имеют тенденцию связывать все имена столбцов, которые содержат 'ID' в слове, ВКЛЮЧАЯ ID !! !

Даже конструктор запросов делает это на Microsoft SQL Server (и для каждого создаваемого вами запроса вы в конечном итоге срываете все ненужные вновь созданные отношения для всех таблиц с идентификатором столбца)

ТАК Как мой внутренний OCD ненавидит это, я катлюсь с соглашением TableID . Давайте вспомним, что он называется Data BASE , так как он, как мы надеемся, станет основой для многих и многих приложений. И все технологии должны быть хорошо отлажены с четким описанием схемы.

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

  • Название таблицы: множественное число. Ex. Сотрудники
  • Псевдоним таблицы: полное имя таблицы, в единственном числе. Ex.

    SELECT Employee.*, eMail.Address
    FROM Employees AS Employee LEFT JOIN eMails as eMail on Employee.eMailID = eMail.eMailID -- I would sure like it to just have the eMail.ID here.... but oh well
    

[Update]

Кроме того, в этой теме есть несколько действительных сообщений о дублированных столбцах из-за «вида отношений» или роли. Например, если в Магазине есть EmployeeID , это говорит мне о приседе. Поэтому я иногда делаю что-то вроде Store.EmployeeID_Manager . Конечно, он немного больше, но как минимум люди не будут сходить с ума, пытаясь найти таблица ManagerID или что там делает EmployeeID . Когда запрашивается ГДЕ, я бы упростил его как: SELECT EmployeeID_Manager в качестве ManagerID из хранилища

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