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

Именование столбцов идентификатора в таблицах базы данных

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

Если у меня есть таблица под названием Invoices с первичным ключом столбца идентификации, я бы назвал этот столбец 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, то очевидно, в какой таблице он находится?

Что думают другие народы по этой теме?

4b9b3361

Ответ 1

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

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

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

Если вы хотите использовать синтаксис USING, разрешенный некоторыми dbs, вы не можете использовать идентификатор.

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

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

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, такая случайная ошибка гораздо менее вероятна и намного легче найти.

Ответ 2

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

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

Ответ 3

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

т. LEFT JOIN Клиенты ON Employee.ID = Customer.EmployeeID

говорит мне не только о том, что эти два связаны, но и является PK, а FK

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

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

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

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

Ответ 7

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

Выбрать
    i.ID, il.ID Из     Счета-фактуры я     Слева присоединиться к счетам-фактурам il         на i.ID = il.InvoiceID

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

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

По-моему, это очень читаемо и просто. Именование переменных как я и il - плохой выбор в целом.

Ответ 8

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

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

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

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

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

Ответ 9

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

Ответ 10

Исходя из этого, с точки зрения формального словаря данных, я бы назвал элемент данных invoice_ID. Как правило, имя элемента данных будет уникальным в словаре данных и в идеале будет иметь одно и то же имя, хотя иногда могут потребоваться дополнительные квалификационные условия на основе контекста, например. элемент данных с именем employee_ID может использоваться дважды в диаграмме org и, следовательно, квалифицироваться как supervisor_employee_ID и subordinate_employee_ID соответственно.

Очевидно, что соглашения об именах субъективны и делятся стилем. Я считаю, что рекомендации ISO/IEC 11179 являются полезной отправной точкой.

Для СУБД я вижу таблицы как коллекции entites (кроме тех, которые содержат только одну строку, например таблицу cofig, таблицу констант и т.д.), например. таблица, где my employee_ID - это ключ, будет называться Personnel. Поэтому сразу соглашение TableNameID не работает для меня.

Я видел стиль TableName.ID=PK TableNameID=FK, используемый для больших моделей данных, и должен сказать, что я нахожу его несколько запутанным: я предпочитаю, чтобы имя идентификатора было одинаковым во всем, т.е. не меняло имя, основанное на том, какая таблица появляется Что-то примечание: вышеупомянутый стиль, кажется, используется в магазинах, которые добавляют столбец IDENTITY (auto-increment) для каждой таблицы, избегая естественных и сложных клавиш в внешних ключах. Эти магазины, как правило, не имеют формальных словарей данных и не строят из моделей данных. Опять же, это всего лишь вопрос стиля и того, к которому я лично не подписываюсь. Так что в конечном счете, это не для меня.

Все, что сказал, я вижу случай, когда иногда отбрасывает квалификатор из имени столбца, когда имя таблицы предоставляет контекст для этого, например. элемент с именем employee_last_name может стать просто last_name в таблице Personnel. Обоснованием здесь является то, что домен является "фамилиями людей" и, скорее всего, будет UNION ed с столбцами last_name из других таблиц, а не использоваться в качестве внешнего ключа в другой таблице, но затем снова... я может просто изменить мой разум, иногда вы никогда не сможете сказать. Это то, что: моделирование данных - это часть искусства, часть науки.

Ответ 11

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

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

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

THUS, так как мой внутренний OCD его ненавидит, я качаюсь с помощью соглашения TableID. Помните, что он называется Data BASE, так как он станет основой для многих многих приложений. И все технологии должны пользоваться хорошо нормированной с четкой схемой описания.

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

  • Имя таблицы: Плюрализировано. 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
    

[Обновление]

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

Ответ 12

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

Что я подразумеваю под первым утверждением, вместо ID вы можете использовать что-то еще, например, "recno". Итак, в этой таблице будет PK invoice_recno и т.д.

Cheers, Бен

Ответ 13

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

 Select Invoice.InvoiceID, Lines.InvoiceLine, Customer.OrgName
 From Invoices Invoice
 Join InvoiceLines Lines on Lines.InvoiceID = Invoice.InvoiceID
 Join Customers Customer on Customer.CustomerID = Invoice.CustomerID

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

Ответ 14

Для имени столбца в базе данных я использую "InvoiceID".

Если я скопирую поля в неназванную структуру через LINQ, я могу назвать ее "ID", если это единственный идентификатор в структуре.

Если столбец НЕ будет использоваться во внешнем ключе, так что он будет использоваться только для уникальной идентификации строки для редактирования или удаления редактирования, я назову его "ПК".

Ответ 15

Если вы укажете каждому ключу уникальное имя, например. "invoices.invoice_id" вместо "invoices.id", то вы можете без проблем использовать "естественное соединение" и "использование" операторов. Например.

SELECT * FROM invoices NATURAL JOIN invoice_lines
SELECT * FROM invoices JOIN invoice_lines USING (invoice_id)

вместо

SELECT * from invoices JOIN invoice_lines
    ON invoices.id = invoice_lines.invoice_id

SQL достаточно многословно, не делая его более подробным.

Ответ 16

Что я делаю для того, чтобы все было согласовано для меня (где таблица имеет первичный ключ одного столбца, используемый как идентификатор), это имя первичного ключа таблицы Table_pk. В любом месте у меня есть внешний ключ, указывающий на первичный ключ этих таблиц, я вызываю столбец PrimaryKeyTable_fk. Таким образом, я знаю, что если у меня есть таблица Customer_pk в моей таблице Customer и Customer_fk в моей таблице заказов, я знаю, что таблица Order ссылается на запись в таблице Customer.

Для меня это особенно важно для объединений, где, по-моему, это легче читать.

SELECT * 
FROM Customer AS c
    INNER JOIN Order AS c ON c.Customer_pk = o.Customer_fk

Ответ 17

FWIW, наш новый стандарт (который меняется, я имею в виду "развивается", с каждым новым проектом):

  • Имена полей базы данных нижнего регистра
  • Имена таблиц верхнего уровня
  • Используйте символы подчеркивания для разделения слов в имени поля - преобразуйте их в регистр Pascal в коде.
  • pk_ префикс означает первичный ключ
  • _id суффикс означает целое число, auto-increment ID
  • fk_ префикс означает внешний ключ (без суффикса)
  • _VW суффикс для представлений
  • is_ префикс для booleans

Итак, таблица с именем NAMES может иметь поля pk_name_id, first_name, last_name, is_alive, и fk_company и представление под названием LIVING_CUSTOMERS_VW, определенное как:

SELECT first_name, last_name
FROM CONTACT.NAMES
WHERE (is_alive = 'True')

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

Ответ 18

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

SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceID = inv.ID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceLineID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceLineID = inv.ID 

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

Ответ 19

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

Ответ 20

Я предпочитаю доменное имя || 'Я БЫ'. (то есть имя домена + идентификатор)

DomainName часто, но не всегда, совпадает с именем TableName.

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

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

Иногда, DomainName || "ID" не может использоваться, потому что в одной таблице с тем же именем будет два столбца. Пример: Employees.EmployeeID и Employees.SupervisorID. В таких случаях я использую RoleName || 'ID', как в примере.

И последнее, но не менее важное: вместо этого я использую естественные ключи, а не синтетические ключи. Бывают ситуации, когда естественные ключи недоступны или ненадежны, но существует множество ситуаций, когда естественный ключ является правильным выбором. В тех случаях я позволяю естественному ключу взять имя, которое оно, естественно, имело бы. Это имя часто даже не имеет букв, "ID" в нем. Пример: OrderNo, где No - аббревиатура для "Номер".

Ответ 21

Для каждой таблицы я выбираю сокращенную букву дерева (например, Employees = > Emp)

Таким образом, числовой первичный ключ autonumber становится nkEmp.

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

Я сохраняю те же имена в SQL и всех языках, которые я использую (в основном, С#, Javascript, VB6).

Ответ 22

См. сайт Interakt соглашения об именах для хорошо продуманной системы именования таблиц и столбцов. В методе используется суффикс для каждой таблицы (_prd для таблицы продуктов или _ctg для таблицы категорий) и добавляется к каждому столбцу в данной таблице. Таким образом, столбец идентификаторов для таблицы продуктов будет id_prd и поэтому уникален в базе данных.

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

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

Ответ 24

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

  • Используйте короткие (3-4 символа) псевдонимы для имен таблиц, то есть счет-фактура - inv, InvoiceLines - invl
  • Назовите столбцы в таблице, используя эти псевдонимы, т.е. inv_id, invl_id
  • Для ссылочных столбцов используйте invl_inv_id для имен.

таким образом, вы могли бы сказать

SELECT * FROM Invoice LEFT JOIN InvoiceLines ON inv_id = invl_inv_id