Соглашение о назначении первичного ключа/внешнего ключа

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

1:

Primary Table (Employee)   
Primary Key is called ID

Foreign table (Event)  
Foreign key is called EmployeeID

или

2:

Primary Table (Employee)  
Primary Key is called EmployeeID

Foreign table (Event)  
Foreign key is called EmployeeID

Я предпочитаю не дублировать имя таблицы в любом столбце (так что я предпочитаю вариант 1 выше). Концептуально это согласуется с множеством рекомендуемых практик на других языках, где вы не используете имя объекта в его именах свойств. Я думаю, что именование внешнего ключа EmployeeID (или Employee_ID может быть лучше) сообщает читателю, что это столбец ID таблицы Employee.

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

Кроме того, я считаю избыточным иметь имя таблицы в имени столбца, потому что, если вы считаете таблицу как сущность и столбец как свойство или атрибут этого объекта, вы считаете это атрибутом идентификатора атрибут Employee, а не EmployeeID сотрудника. Я не спрашиваю своего коллегу, что такое его PersonAge или PersonGender. Я спрашиваю его, что такое его возраст.

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

Ответ 1

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

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

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

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

Ответ 2

Если оба столбца имеют одинаковое имя в обеих таблицах (соглашение № 2), вы можете использовать синтаксис USING в SQL для сохранения некоторого набора текста и некоторого шаблонного шума:

SELECT name, address, amount
  FROM employees JOIN payroll USING (employee_id)

Еще один аргумент в пользу соглашения № 2 заключается в том, что он разработал способ реляционной модели.

Значение каждого столбца частично передается путем маркировки его имя соответствующего домена.

Ответ 3

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

Мне нравится кодировать базу данных как свой собственный слой. Я контролирую все, и приложение просто вызывает хранимые процедуры. Приятно иметь наборы результатов с полными именами столбцов, особенно когда есть много таблиц и много столбцов. С этим типом приложения мне нравится вариант 2. Мне очень нравится видеть совпадение имен столбцов на объединениях. Я работал над старыми системами, где они не совпадали, и это был кошмар,

Ответ 4

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

например, для таблицы саморегуляции, когда имеется более одного столбца FK, который самоназывает одну и ту же таблицу PK, вы должны нарушать оба "стандарта", поскольку два столбца FK нельзя назвать одинаковыми... например, EmployeeTable с EmployeeId PK, SupervisorId FK, MentorId Fk, PartnerId FK,...

Ответ 5

Я согласен, что между ними мало выбора. Для меня гораздо более значительная вещь в любом стандарте - это "стандартная" часть.

Если люди начинают "делать свое дело", они должны быть нанизаны их лапами. ИМХО:)

Ответ 6

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

  • Табличные определения обычно непосредственно сопоставляются с классом, который описывает один объект, поэтому они должны быть единственными. Чтобы описать коллекцию объекта, я обычно добавляю "Массив" или "Список" или "Коллекция" к единственному имени, поскольку он более четко, чем использование множественных чисел, указывает не только на то, что это коллекция, но и какая коллекция это. В этом представлении я вижу имя таблицы, а не имя коллекции, но имя типа объекта, частью которого является коллекция. Администратор базы данных, который не пишет код приложения, может пропустить эту точку.

  • В данных, к которым я имею дело, часто используется идентификатор "ID" для целей нецелевого идентификации. Чтобы устранить путаницу между ключевыми "идентификаторами" и не-ключевыми "идентификаторами", для имени первичного ключа мы используем "Ключ" (это то, что это такое, не так ли?) С префиксом имени таблицы или аббревиатуры имя таблицы. Это префикс (и я оставляю это только для первичного ключа) делает ключевое имя уникальным, что особенно важно, потому что мы используем имена переменных, которые совпадают с именами столбцов базы данных, и большинство классов имеют родителя, идентифицированного по имени родительский ключ. Это также необходимо, чтобы убедиться, что это не зарезервированное ключевое слово, которое является "ключевым". Чтобы упростить сохранение ключевых имен переменных согласованным и обеспечить программы, которые выполняют естественные объединения, внешние ключи имеют то же имя, что и в таблице, в которой они являются первичным ключом. Я не раз сталкивался с программами, которые работают намного лучше, используя естественные объединения. В этом последнем пункте я допускаю проблему с таблицами саморегуляции, которые я использовал. В этом случае я бы сделал исключение из правила именования внешнего ключа. Например, я бы использовал ManagerKey в качестве внешнего ключа в таблице Employee, чтобы указать на другую запись в этой таблице.

Ответ 7

Мне нравится соглашение # 2 - в исследовании этой темы и поиске этого вопроса, прежде чем публиковать мои собственные, я столкнулся с проблемой, где:

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

SELECT table1.id AS parent_id, table2.id AS child_id

Хотя использование соглашения # 2 означает, что у меня все равно будут некоторые столбцы в результате с тем же именем, теперь я могу указать, какой идентификатор мне нужен (родительский или дочерний), и, как предложил Стивен Хьюиг, оператор USING упрощает в дальнейшем.

Ответ 8

Я всегда использовал userId как ПК в одной таблице и userId в другой таблице как FK. "Мы серьезно думаем об использовании userIdPK и userIdFK как имена для идентификации одного из другого. Это поможет мне быстро идентифицировать ПК и FK при просмотре таблиц, и похоже, что он очистит код при использовании PHP/SQL для доступа к данным, что упростит их понимание. Особенно, когда кто-то еще смотрит на мой код.

Ответ 9

Соглашение, которое мы используем, когда я работаю, довольно близко к A, за исключением того, что мы называем таблицы во множественном числе (например, "сотрудники" ) и используем подчеркивания между таблицей и именем столбца. Преимущество этого заключается в том, что для ссылки на столбец это либо "employee _ id", либо "employee.id", в зависимости от того, как вы хотите получить к нему доступ. Если вам нужно указать, из какой таблицы следует столбец, "employee.employees _ id" определенно избыточно.

Ответ 10

Я использую соглашение # 2. Сейчас я работаю с устаревшей моделью данных, где я не знаю, что стоит в данной таблице. Где вред быть подробным?

Ответ 11

Как именовать внешний ключ

ROLE_ID

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

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

В любом случае havin long аргументы - плохая идея

Ответ 12

"Где в" сотруднике INNER JOIN order on order.employee_id = employee.id "есть ли необходимость в дополнительной квалификации?".

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

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

Молитесь, скажите мне, если столбец называется "ID", то как это "ссылается на [sic] на таблицу" выполняется точно, если только не квалифицируя эту ссылку на столбец идентификатора точно так, как я говорил?

Ответ 13

Вы считали следующее?

Primary Table (Employee)   
Primary Key is PK_Employee

Foreign table (Event)  
Foreign key is called FK_Employee