Чому іменування стовпця первинного ключа "Id" вважається поганою практикою? [зачинено]


210

Мій учитель t-sql сказав нам, що називати наш стовпець ПК "Id" вважається поганою практикою без додаткових пояснень.

Чому називання таблиці PK стовпцем "Id" вважається поганою практикою?


27
Ну, це не опис насправді, а Id означає "ідентичність", що дуже пояснює себе. Це моя думка.
Жан-Філіп Леклерк

49
Я впевнений, що є багато магазинів, які використовують ІД як назву ПК. Я особисто використовую TableId як свою умову іменування, але я нікому не розповідав про його ПРАВИЛЬНИЙ ШЛЯХ. Здається, що ваш вчитель просто намагається представити її думку як широко прийняту найкращу практику.

22
Безумовно, тип поганої практики, який не так вже й поганий. Сенс у тому, щоб бути послідовним. Якщо ви використовуєте id, використовуйте його скрізь або не використовуйте.
deadalnix

57
У вас є таблиця ... вона називається Люди, вона має стовпець, що називається Id, як ви думаєте, що Id? Машина? Човен? ... ні, це People Id, це все. Я не думаю, що це не погана практика, і не потрібно називати PK стовпчиком нічого, крім Id.
Джим

38
Тож учитель встає перед класом і каже вам, що це погана практика без єдиної причини? Це гірша практика для вчителя.
JeffO

Відповіді:


247

Я збираюся вийти і сказати: Це на самому ділі не погана практика (і навіть якщо він є, його не що погано).

Ви можете зробити аргумент (як вказував Чад ), що він може маскувати помилки, як у наступному запиті:

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

але це легко пом'якшити, не використовуючи крихітних псевдонімів для назв таблиці:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId

Практика ЗАВЖДИ з використанням 3-х літерних скорочень мені здається набагато гіршою, ніж використання назви стовпців id. (Справа в точці: хто насправді скоротить назву таблиці carsабревіатурою car? Який кінець це служить?)

Сенс у цьому: бути послідовним. Якщо ваша компанія використовує Id і ви часто робите помилку вище, тоді звикайте використовувати повні таблиці імен. Якщо Ваша компанія забороняє стовпчик Id, поступово виконайте його і використовуйте будь-яку угоду про іменування, яку вони вважають за краще.

Зосередьтеся на вивченні речей, які САМО погані практики (наприклад, кілька вкладених співвіднесених підзапитів), а не обдумування таких питань. Питання іменування своїх стовпців "ідентифікатором" ближче до питання смаку, ніж до поганої практики.


ПРИМІТКА ДЛЯ РЕДАКТОРІ: помилка в цьому запиті навмисна і використовується для визначення точки. Будь ласка, прочитайте повну відповідь перед редагуванням.


1
@Chad, це було посиланням на те, що в цьому конкретному запиті ви використовували 3 букви для псевдонімів для імен таблиць, навіть коли це не мало сенсу ( cars-> car. Слава Богу - ви зберегли мені пальці). Не читайте це занадто глибоко.
riwalk

3
гірше, ніж мої псевдоніми, було мішання множини carsта manufacturer. Одне - множина, інше - ні. Якщо люди хочуть забрати у db, це погана практика, яку слід обрати.
CaffGeek

3
Я думаю, що це погана практика. Очевидно, що щодо поганої практики це не страшно .. але це так просто уникнути, чому б не зробити цього? Тепер я погоджуюся, що для вступного класу, на цьому варто зосередити увагу? Напевно, немає ....
user606723

2
@ user606723, насправді, я думаю, що для вступного класу важлива річ. Навчання кращим практикам має бути основним. Це лише тоді, коли ви відчуєте, що ви розумієте наслідки та компроміси, і коли вам слід відхилитися від найкращих практик.
CaffGeek

5
@Chad, погоджуюсь не погоджуватися. Намагатись навчити учнів "найкращих практик", не даючи їм зрозуміти, чому це найкращі практики, - марне зусилля. І оскільки ви не можете все охопити, промальовуючи цю точку «просто не варто цього робити, ви зрозумієте, чому пізніше» - це досить розумний вибір з точки зору професора. Допитливі студенти можуть опублікувати тут або сподіваємось знайти це питання вже відповіли. (Або запитати після уроку)
user606723

123

Тому що, коли у вас є таблиця із зовнішнім ключем, ви не можете назвати цей зовнішній ключ "Id". Ви маєте назву таблиці TableId

І тоді ваше приєднання виглядає так

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId

І в ідеалі ваш стан повинен мати однакову назву поля з усіх боків

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId

Отже, хоча ідентифікатор Id називається ManufacturerId, але це робить менш ймовірним виникнення помилок в умовах приєднання, оскільки помилки стають очевидними.

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

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Тоді як при правильному іменуванні помилка видається ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId

Ще одна причина, що називає їх Id "поганим", полягає в тому, що коли ви запитуєте інформацію з декількох таблиць, вам потрібно буде перейменувати стовпці Id, щоб ви могли їх розрізнити.

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id

З точними іменами це менше питання


174
Не впевнений, що це досить хороше пояснення для мене. Немає нічого поганого в тому, щоб сказати SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId. Я використовував idроками і ніколи не виявив те, що ви описали, як справжню проблему.
riwalk

61
Я б сказав, що погана практика тут полягає у наданні псевдонімів таблиць з назвою, наприклад mfg або mod. виробників.id = cars.manufacturer_id дуже читабельна, і помилка також вичерпається.
deadalnix

5
@Chad> У мене вже виникли проблеми з німими назвами змінних. Багато разів. Для врахування, ось що я сказав би розробнику, який робить це в моїй команді «mfg не означає виробника, це означає, що ти лінивий тип виробника».
deadalnix

9
@ Stargazer712: Вибір SELECT * з 2 таблиць дає 2 x стовпці ідентифікатора. Ідентифікатор тепер неоднозначний: ви посилаєтесь на порядок чи ім’я? SELECT * теж не є хорошою практикою. Погані аргументи. Крихкий код. Чад правильний: оборонне кодування в основному
gbn

6
@gbn, знову ж таки, вся двозначність піде, якщо ви просто зробите це SELECT manufacturer.id FROM .... Кожну складність, що виникає в результаті, idможна подолати дуже легко, зробивши це просто справою смаку.
riwalk

67

Бібліотека ActiveRecord Ruby та GORM Groovy за замовчуванням використовують "id" для сурогатного ключа. Мені подобається така практика. Дублювання назви таблиці у кожному імені стовпця є зайвим, нудним для запису та більш стомливим для читання.


30
+1 для "і більш нудно читати". - імена конвенцій не слід розглядати як смугу допомоги для неохайного коду, вони повинні покращувати читабельність як основну проблему.
окудо

12
Ідентифікатор набагато
втомливіше

5
@HLGEM: Ім'я стовпця завжди можна визначити назвою стовпця.
кевін клайн

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

2
+1, Ненавиджу бачити таблиці зі стовпцями, як Posts.postID, Posts.postName, де просто використовувати post.id та post.name набагато красивіше.
Дуг

40

Загальні або ключові назви стовпців, наприклад, "Ім'я" або "Ідентифікатор", повинні мати префікс таблиці "Таблиця".

Це усуває двозначність, простіше шукати, означає набагато менше псевдонімів стовпців, коли потрібні обидва значення "Id".

Менш використаний або стовпець аудиту або неклавішний (скажімо LastUpdatedDateTime) значення не має


57
Якщо ви це робите, я ненавиджу вас за те, що я змушував вас зайвий набирати текст !!!! Ім'я таблиці - Особа, як ви думаєте, що буде Id? Автомобіль? ні, це Особа.
Джим

16
@jim, я не знаю про тебе, але введення 6 зайвих символів займає у мене приблизно півсекунди. Зважаючи на те, що я рідко коли-небудь вибираю з однієї таблиці, і, таким чином, у кінцевому підсумку вийде два стовпчики з назвою "Id", і потрібно буде так чи інакше включати ім'я таблиці / псевдоніма, немає жодної економії в кількості введених символів.
CaffGeek

21
@Chad Я вважаю це зайвим. якщо я роблю приєднання, c.id = m.manufacturerid, зі мною все в порядку. Ці стовпчики, як правило, "відображаються" до класу якось і мати клас з Person.PersonId змушує мене блювати ... Так, я повністю усвідомлюю, що у мене є проблеми.
Джим

20
Я також не згоден з цим. Навіщо зупинятися на nameта id? Чому б у кожному стовпці не було вказано назву таблиці? Мабуть, довільно вибрати ці два імена для призначення префікса. Концептуально ви повинні мати таблицю, щоб у будь-якому випадку мати контекст стовпця. Чому б просто не використовувати цю назву таблиці для уточнення запиту: Person.Name, Animal.Name, Part.Name, ...
Thomas

11
@Bill Leeper, DRY не завжди підходить при розробці бази даних. У базах даних важлива ефективність та змушення бази даних виконувати додаткову роботу для повноцінного заповнення принципів DRY (наприклад, використання скалярних функцій або представлень, що викликають перегляди чи запити, які повертають занадто багато стовпців, або за допомогою курсору для додавання 1000000 записів для використання наявного протоколу) часто протипоказаний. Не думайте, що лише тому, що щось добре в об'єктно-орієнтованому світі, це доречно в дизайні бази даних. Ваш голос був недоречним. Використання ID - відомий антипатерн SQL.
HLGEM

31

Цей потік мертвий, але я хотів би додати , що ІМО НЕ використовуючи Idце погана практика. IdКолона є особливим; це первинний ключ. Будь-яка таблиця може мати будь-яку кількість сторонніх ключів, але вона може мати лише один ключ, який є первинним. У базі даних, де викликаються всі первинні ключі , як тільки ви дивитесь на таблицю, ви точно знаєте, який стовпець є первинним ключем.Id

Повірте, я вже місяцями щодня витрачаю цілий день, працюючи в багатьох великих базах даних (Salesforce), і найкраще, що я можу сказати про схеми, - це те, що в кожній таблиці є виклик первинного ключа Id. Можу запевнити, що я абсолютно ніколи не плутаюсь щодо приєднання первинного ключа до іноземного ключа, оскільки викликається ПК Id. Інша річ, про яку люди не згадували - це те, що таблиці можуть мати довгі нерозумні назви Table_ThatDoesGood_stuff__c; це ім'я досить погано, оскільки архітектор мав похмілля вранці, коли він придумав цю таблицю, але тепер ви говорите мені, що погана практика не викликати первинний ключ Table_ThatDoesGood_stuff__cId (пам’ятаючи, що імена стовпців SQL взагалі не чутливі до регістру).

Якщо чесно, проблеми з більшістю людей, які навчають комп'ютерному програмуванню, полягають у тому, що вони не написали коду виробничого коду за роки, якщо ніколи, і не мають поняття, що насправді працює інженер з програмного забезпечення. Зачекайте, поки ви почнете працювати, а потім складіть свою думку про те, що ви вважаєте гарною ідеєю чи ні.


2
Це лише в тому випадку, якщо жоден з ваших первинних ключів не є складеним ключем, що, на жаль, занадто часто трапляється. Справді слід використовувати сурогатні ключі лише за певних обставин.
nicodemus13

6
Використовуючи подібний Id, ви потрапляєте в ситуацію, коли розробники не замислюючись додають ідентифікатор первинного ключа до кожної таблиці, яку вони створюють. Однією з основ реляційних баз даних є використання значущих та сукупних первинних ключів, а використання id не допомагає.
Пітер Б

Ця відповідь просто схожа на те, що ви говорите «я вважаю за краще Id» із суперечливими аргументами. Ваш аргумент полягає в тому, що ви можете миттєво побачити, який ключ є первинним ключем, знайшовши той, який називається Id. Ну, це точно так само і з tableId . Я можу вам гарантувати, що я ніколи не плутаюсь, який ключ є і первинним ключем. Я просто шукаю ту, яка має ім’я таблиці перед ідентифікатором. Мало того, але з якими язичницькими таблицями ви працюєте, де перший стовпець не є первинним ключем? Я відчуваю, що всі ваші аргументи у цій відповіді мають суто преференційну основу і схожі на "tableId мені не так".
Даллін

@dallin всі відповіді сумнівні, інакше хтось би просто посилався на офіційний стандарт, а його немає!
Джеймс

@James Я відчуваю, що мета сайтів StackExchange - зменшити впевнені відповіді. Ось чому питання закриваються як занадто самовпевнені. Зрозуміло, я думаю, що це питання, чому це питання було закрито - тому що воно викликає сумнівні відповіді, але я вважаю, що ця конкретна відповідь була надмірно виражена без реальних підтверджуючих фактів чи аргументів, заснованих на фактах. Всю відповідь можна підсумувати, сказавши: на мою думку, ви повинні використовувати Id, тільки тому, що це мені подобається ". Це не цінна відповідь.
Даллін

24

Я не вважаю це поганою практикою. Консистенція королева, як завжди.

Я думаю, це все в контексті. У контексті самої таблиці "id" означає саме те, що ви очікуєте, мітка, яка допомагає однозначно ідентифікувати її проти інших, які в іншому випадку можуть бути (або видатися) однаковими.

У контексті приєднань, ви несете відповідальність за конструювання приєднань таким чином, щоб зробити їх читабельними для вас та вашої команди. Так само, як можна ускладнити речі при поганому фразуванні чи називанні, так само можливо створити змістовний запит з ефективним використанням псевдонімів і навіть коментарів.

Таким же чином, клас Java під назвою "Foo" не має своїх властивостей з префіксом "Foo", не відчувайте зобов'язання префіксувати ваші ідентифікатори таблиці з іменами таблиць. Зазвичай в контексті зрозуміло, що таке ідентифікатор.


5
Таблиці реляційних баз даних не є класами .
Адам Робінсон

1
Однак вони є структурою даних і аналогічні класам PODO. Стосовно ж іменних проблем.
ocodo

4
@Slomojo: Ні, вони не аналогічні простим об'єктам. Об'єктно-орієнтований дизайн та дизайн баз даних не є однаковим і навіть не пов’язані між собою. Хоча вони можуть у деяких випадках отримати подібний (або навіть однаковий) дизайн, що не означає, що вони пов'язані. Наприклад, m: m відносини тривіальні в класах, але неможливо мати між двома таблицями без третьої таблиці асоціацій.
Адам Робінсон

1
Навіть як це стосується стратегії іменування, я не знаю. Моя аналогія (чітко?) Лише в цій мірі розкрита.
ocodo

2
Вибачте, що мається на увазі мій сенс був не дуже зрозумілим, я повинен був сказати, " в цьому сенсі вони аналогічні класам". Так чи інакше, я не думаю, що надмірно педантичний щодо цього є особливо конструктивним. Що стосується імен, таблиці та класи поділяють значну кількість подібності. Найкращі практики, які розвиваються в культовому мішку, - це чесна гра для перегляду або, принаймні, відкрита для обговорення. В цьому питанні багато, що це наочно ілюструє, я не маю нічого іншого зауваження додати.
ocodo

24

З data.stackexchange.com

Повідомлення в дописах

БУМ, відповів на запитання.
Тепер іди, скажи своєму вчителю, що ТАК практикує поганий дизайн бази даних.


8
Моя здогадка в ФКС, на основі імен: PostTypeId -> PostTypes.Id; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id. Чому така простою практикою слід вважати «поганою»?
Шьорд

3
Як саме це доводить що-небудь про кращі практики?
ГБа

5
Чи використовується щось у стеці чи ні, це не доводить, чи це хороша чи погана практика.
Пітер Б

2
Це доводить, що ця практика жодним чином не забороняє масштабованість та корисність програми.
Cypher

1
Насправді ТАК практика не є досконалою. Я б використав це найменування: PostType -> PostType.Id; AcceptedAnswer -> Answer.Id; OwnerUser -> User.Id
alpav

17

Це важко (і заплутано) виконувати природне поєднання на столі, тому так, це погано, якщо не дуже погано.

Natural Join - це древній артефакт SQL Lore (тобто реляційна алгебра), можливо, ви бачили одне із них: perhaps можливо у книзі баз даних. Що я маю на увазі, що Natrual Join - це не нова фантастична ідея SQL, хоча, як це було схоже, візьмуть її СУБД назавжди, тому це не нова фантастична ідея для її реалізації, це може бути навіть нерозумно для вас ігнорувати його існування нині.

Ну, якщо ви назвете всі ідентифікатори свого основного ключа, то ви втратите легкість і простоту природного з'єднання. select * from dudes natural join carsмає бути написано select * from dudes inner join cars where cars.dudeid = dudes.idабо select * from dudes inner join cars where dudes.carid = cars.id. Якщо вам вдасться зробити природне приєднання, ви ігноруєте, що насправді є відношенням, що, я вважаю, є досить приголомшливим.


Якщо ви не пишете збережену процедуру, коли останній раз як розробник програми ви насправді написали повністю відформатований селектор SQL? Сучасні мови включають в себе певну функцію ORM, яка керує цим відносинами для вас. Назва стовпця набагато важливіша, ніж можливість писати чистий посібник SQL.
Білл Лепер

4
@Bill Я весь час, багато, багато разів на день, більше залежить від вашої кодової бази, ніж від мови, яку ви розробляєте. А для діагностики, якщо ви хочете зробити добрі і глибокі відносини, ви можете з'єднати ці природні з'єднання і повністю уникати пошуку ідентифікаторів поля. І, як чудово сказав святий Єронім, "Незнання SQL - це незнання баз даних".
Пітер Тернер

Окрім того, що природні приєднання не підтримуються повсюдно, ІМО, природні приєднання важче читати. Чи є два стовпці у взаємозв'язку чи лише одна? Набагато краще бути явним і уникати природних приєднань.
Томас

1
@Thomas, я також не ставлю природні приєднання до коду, але для діагностики я вважаю їх досить корисними, коли база даних моделюється так, що вони фактично працюють.
Пітер Тернер

16

Існує ситуація, коли наклеювати "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)

Це відповідь, яка найбільше стикається для мене. USINGКлючове слово підтримується базою даних Postgres / MySQL / SQLite, означає менше друкувати , які деякі зі списку інших відповідей в якості причини для використання id, і , нарешті , на мою суб'єктивну думку , є більш зручним для читання.
Майкл Бартон

11

Чому б просто не запитати свого вчителя?

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

Назви стовпців мають бути семантично значущими. IDє загальним.


8
занадто загальне для чого? ідентифікатор таблиці?
Джим

3
@Jim якого столу? idпоодинці нічого не означає, особливо в контексті іноземного ключа до іншої таблиці. Це не має нічого спільного classesі все, що стосується гарного базового дизайну реляційних баз даних.

10
Щоб бути трохи жирним, стіл, якому він належить. table.id- цілком прийнятний спосіб посилання на idполе. Префіксація назви поля із назвою таблиці зайва.
ocodo

2
@Slomoj - це не більше введення тексту, ніж включення імені в стовпчик і більше експлікації, коли псевдоніми імен таблиць до одно- або подвійних літерних абревіатур у монстрі приєднуються.

6
Про який кошмар ви посилаєтесь? Припустимо, у вас є структура, що посилається на себе, зі стовпцем, який представляє їх керівника. Як ви називаєте іноземний ключ? Ви не можете назвати його EmployeeId, оскільки, мабуть, це ваш ПК. Назва ФК не повинна відповідати ПК. Його слід назвати тим, що воно представляє суб'єкту, в якому воно міститься.
Томас

7

Ідентифікатор поганий з наступних причин:

Якщо ви робите багато запитів щодо звітування, вам завжди доведеться псевдоніми стовпців, якщо ви хочете бачити обидва. Таким чином, це стає марною витратою часу, коли ви можете назвати це належним чином. Ці складні запити досить важкі (я пишу запити, які можуть бути довгими сотнями рядків) без додаткового навантаження на непотрібну роботу.

Це може спричинити помилки коду. Якщо ви використовуєте базу даних, яка дозволяє використовувати природне приєднання (не те, що я думаю, ви коли-небудь повинні використовувати це, але коли є доступні функції, хтось їх використовуватиме), ви приєднаєтесь до неправильної речі, якщо отримаєте розробника, який це використовує.

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


+1: На мою думку, це вагомі причини, тоді як інші відповіді, що протистоять ID, мене зовсім не переконують.
понеділок

Re: "Якщо ви копіюєте приєднується, щоб створити складний запит" - тож ваша проблема - скопіювати та вставити. Зупиніть копіювати та вставити, і ви побачите, як зручно називати car.id. Для приєднання до FK використовуйте car.mfg = mfg.id, car.color = color.id, car.model = model.id - дуже просто і відповідає тому, що ви б написали в LINQ.
alpav

Спробуйте написати щось із 30 приєднаннями, і ви побачите, чому це антипатерн.
HLGEM

Відчуження - це перша і головна причина - це такий головний біль при складанні великих складних звітів. Природні приєднання - це лише солодкий бонус. Дивно, як інші відповіді просто ігнорують ці моменти. Я думаю, що додавання декількох прикладів зробить точку зрозумілішою і підніме цю відповідь вище, де вона повинна бути.
Лулу

5

Є кілька відповідей, які підходять до того, що я вважаю найважливішою причиною не використовувати "id" як назву стовпця для основного ключа в таблиці: а саме послідовність та зменшена неоднозначність.

Однак для мене ключову перевагу реалізує програміст з технічного обслуговування, зокрема той, хто не був причетний до оригінальної розробки. Якщо ви використовували ім'я "PersonID" для ідентифікатора в таблиці Person і послідовно використовували це ім'я як зовнішній ключ, тривіально написати запит проти схеми, щоб дізнатися, які таблиці мають PersonID, не роблячи висновку, що "PersonID" це ім'я, яке використовується, коли це іноземний ключ. Пам'ятайте, правильно чи неправильно, зовнішні ключові відносини не завжди застосовуються у всіх проектах.

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

Так, багато цього може бути досягнуто стандартом наявності "id" та знанням завжди використовувати його як "tableNameID", але для цього потрібно знати як, що практика існує, так і залежно від оригінальних розробників. інтуїтивно зрозуміла стандартна практика.

Хоча деякі люди наголошували, що для запису довших назв стовпців потрібні додаткові натискання клавіш, я вважаю, що написання коду є лише невеликою частиною активного життя програми. Якщо збереження натискань клавіш розробника було метою, коментарі ніколи не слід писати.

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


Припустимо, у Companiesтаблиці є 2 зовнішніх ключа до Personsстолу. Один представляє президента компанії; інший представляє скарбника компанії. Ви б дійсно називали стовпчики PersonID1і PersonID2? Набагато більш описовим було б їх назвати PresidentIDі TreasurerID. Мені це набагато легше читати, inner join Person AS Presidents ON Company.PresidentID = Presidents.IDніжinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
понеділок

1
Ні. У вашому прикладі я, мабуть, мав таблицю CompanyOfficerабо CompanyPersonтаблицю, яка дозволяє взаємозв'язок між багатьма Companyі Personз додатковою інформацією про характер відносин. Якби я реалізував це в Companyтаблиці, я б використав імена стовпців PresidentPersonIDі TreasurerPersonIDзберег би * PersonID частину імені, додаючи додатковий дескриптор. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Малачі

5

Практика використання Id як поля первинного ключа призводить до того, що id додається до кожної таблиці. У багатьох таблицях вже є унікальна інформація, яка однозначно ідентифікує запис. Використовуйте ТО як основний ключ, а не ідентифікаційне поле, яке ви додаєте до кожної таблиці. Це одна з основ реляційних баз даних.

І тому використання id - це погана практика: ідентифікатор часто не є інформацією, а лише автоматичним збільшенням.

розглянемо наступні таблиці:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands

Що не так у цій таблиці, це те, що вона дозволяє користувачеві додати ще один рядок: США, з кодом країни 840. Він просто порушив реляційну цілісність. Звичайно, ви можете надати унікальність для окремих стовпців, або ви можете просто використовувати первинний ключ, який уже доступний:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands

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


1
Ви зрозумієте, чому люди додають загальний стовпчик ключів до кожної таблиці, коли вам довелося мігрувати бази даних між різними системами або мали задоволення об'єднувати бази даних разом.
Cypher

1
Іноді це трапляється, але, на мій досвід, досить рідко є непоганий унікальний непорушний ключ. Але навіть у вашому прикладі ви маєте безглузде унікальне число для ідентифікації країн, лише одне, яке ISO виділяється не вашою базою даних.
CodesInChaos

А тепер, коли назва країни зміниться, вам доведеться її оновлювати протягом усієї бази даних, щоб виправити. Якби ви просто використовували сурогатний ключ (наприклад, "id"), оновлення було б тривіальним. Натуральні ключі чудові - коли вони повністю незмінні, і ніколи не змінюються. Насправді дуже мало випадків, коли це правда.
Геррат

@Gerrat: Якщо назва країни змінюється, числовий код ISO 3166-1 залишається однаковим, змінюються лише коди ISO 3166-1 alpha-2 та alpha-3. Так сталося, наприклад, з Бірмою / М'янмою. Так само, якщо країна змінює свою територію, але зберігає свою назву, числовий код ISO 3166-1 змінюється, але ISO 3166-1 альфа-2 та альфа-3 залишаються. Це сталося, коли Південний Судан відрізався від Судану, а Еритрея відкололася від Ефіопії. Коли Східна та Західна Німеччина об'єдналися, вони зберігали коди альфа-2 та альфа-3 Західної Німеччини, але отримали новий цифровий код. Коли країни повністю розсмоктуються або трансформуються (подумайте…
Jörg W Mittag

… Результат Балканських воєн 90-х) вони отримують як нові числові, так і альфа-2 та альфа-3 коди.
Йорг W Міттаг

4

Я завжди використовую "id" як основну назву стовпця для кожної таблиці просто тому, що це умова рамки, яку я використовую (Ruby on Rails, CakePHP), тому мені не потрібно весь час переосмислювати її.

Це не переможе академічні причини для мене.


2

Я не думаю, що це погана практика, якщо вона використовується правильно. Зазвичай є поле з автоматичним збільшенням ідентифікатора під назвою "Ідентифікатор", до якого ніколи не потрібно торкатися, та використовувати дружніший ідентифікатор для програми. Написати код, як, наприклад, може бути дуже громіздким, from tableA a inner join tableB b on a.id = b.a_idале цей код можна витягнути.

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


Ви ніколи не приєднаєтесь до двох таблиць, використовуючи первинний ключ eaches, особливо ідентифікатор автоматичного збільшення. Вибірка вище буде з tableA внутрішньої таблиці приєднанняB b на a.id = b.table_a_id.
Білл Ліпер

Так, це я мав на увазі. Майже в обід і потрібна енергія.
Уейн Моліна

2

Ідентифікатор досить поширений, і я не думаю, що це когось бентежить. Ти завжди хочеш знати таблицю. Введення імен полів у виробничий код, не включаючи таблицю / псевдонім, є поганою практикою. Якщо ви надто стурбовані можливістю швидко вводити спеціальні запити, ви самостійно.

Сподіваємось, ніхто не розробляє базу даних sql, де ID - це зарезервоване слово.

CREATE TABLE CAR (ID);

Дбає про назву поля, первинний ключ та автоматичні кроки на 1, починаючи з 1 все в одному приємному пакеті з 2 символами. О, і я б назвав це АВТОМОБІЛІ, але якщо ми збираємося заощадити на натисканнях клавіш і хто насправді думає, що таблиця під назвою CAR буде мати лише одну?


1
це показує, чому важливі знання формальної теорії реляцій, назва таблиці являє собою те, що є одним рядком . Таблиця Carявляє собою місце, Tableде кожен Rowпредставляє єдину Car. Звернення Carsзміни змістовно і показує повне нерозуміння формальних теорій реляційних основних принципів. Рейки - це прекрасний приклад того, хто знав достатньо, щоб бути небезпечним .

2

Це питання знову і знову побито, але я подумав, що я теж додам свою думку.

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

  2. Поле id - це автоматичне збільшення, не підписане (це означає, що я ніколи не повинен встановлювати його значення, і це не може бути негативним)

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

  4. id короткий і милий теж

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


1

Інша річ, яку слід врахувати, це те, що якщо ім'я первинного ключа відрізняється від імені іноземного ключа, то використовувати певні інструменти сторонніх виробників неможливо.

Наприклад, ви не зможете завантажити вашу схему в такий інструмент, як Visio, і дозволити їй створити точні ERD.


Це була б помилка стороннього інструменту. Конвенції про іменування стовпців не заміняють фактичні закордонні ключі, які інструмент повинен вводити в перспективу.
Геррат

1

Я вважаю, що люди тут висвітлюють майже кожен аспект, але хочу додати, що "id" не є і не повинен читатися як "ідентифікатор", це більше "індекс", і, безумовно, він не вказує і не описує особу рядка. (Я, можливо, тут використав неправильне формулювання, будь ласка, виправте мене, якщо я це зробив)

Це більш-менш те, як люди читають дані таблиці та як вони пишуть свій код. Я особисто, і, швидше за все, це найпопулярніший спосіб, який я бачу частіше, це те, що кодери пишуть повне посилання table.id, навіть якщо їм не потрібно робити об'єднання або / і приєднуватися. Наприклад:

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

Таким чином, ви можете перекласти це англійською мовою як "Дайте мені колір та модель того автомобіля, який пронумерований як". а не як "Дайте мені колір та модель того автомобіля, який ідентифікується як номер". Ідентифікатор ніяк не представляє автомобіль, це лише індекс автомобіля, серійний номер, якщо ви хочете. Так само, як коли потрібно взяти третій елемент з масиву.

Отже, підсумовуючи те, що я хотів додати, це те, що це лише питання переваги, а описаний спосіб читання SQL є найпопулярнішим.

Хоча, є деякі випадки, коли це не використовується, наприклад (набагато більш рідкісний приклад), коли ідентифікатор - це рядок, який справді описує. Наприклад id = "RedFordMustang1970"або щось подібне. Я дуже сподіваюся, що я міг би це пояснити хоча б, щоб отримати ідею.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.