Для чого використовуються негативні ключі?


12

Дещо нове у використанні стандартних баз даних SQL (в даний час працюю з MySQL здебільшого), я ще не працював у багатьох випадках.

Коли і чому корисно мати негативні (а точніше підписані) ключі, що індексують таблицю?


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

1
Ця тема інтригуюча. Я особисто ніколи не чув про цю концепцію. Це питання ніколи не слід було оскаржувати. +1 від мене за впровадження цієї концепції.
RolandoMySQLDBA

Відповіді:


13

Весь первинний ключ - це значення, яке ми визначили, це значення, яке є надзвичайно важливим у записі. Незалежно від того, чи є цей ключ підписаним int, непідписаним int, рядком, blob (насправді, є обмеження) або UUID (або якою б його назвою вона займається сьогодні), факт все ще означає, що це ключ, і що це річ надзвичайно важлива.

Оскільки ми не обмежуємося використовувати лише ключі, орієнтовані на позитивні, для цього є сенс вважати, що підписаний int складе лише ~ 2 мільярди, тоді як неподписаний int складе ~ 4 мільярди. Але немає нічого поганого в тому, щоб використовувати підписаний int, встановити початкове значення ~ -2 мільярда і встановити приріст одного. Після ~ 2 мільярдів записів ви наберете нуль, а потім продовжите ~ 2 мільярди.

Щодо того, чому було б корисно мати «негативні ключі» в таблиці, це те саме питання, що і «чому корисно мати ключі в таблиці». "Значення" ключа не впливає на його статус ключа. Ключ - ключ, ключ.

Важливо, якщо ключ дійсний.

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

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

Що робити, якщо ви хотіли мати таблицю користувачів та вкажіть, що ті, хто має негативні цифри, контролювалися системою (ТАК це дуже важливо для користувачів каналу чату).

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


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

1
@Garet ~ Отже, ви добре зазначаєте: "значення ключа було якось корисно в кодуванні", і я час від часу використовую свої ключі саме таким чином, але це не має нічого спільного з аспектом бази даних. База даних - це сховище. Програма, яка споживає дані, з іншого боку, піклується про значення . Але так, що +/- булевий акуратний трюк, я бачив, що він багато разів використовував саме такий ефект.
jcolebrand

2
-1 для того, щоб зрозуміти, що подвійні цілеспрямовані цінності, як це, є чимось, крім поганої ідеї. Вам потрібні int і bool? Використовуйте інт і бул.
Джек каже, спробуйте topanswers.xyz

1
@JackPDouglas Я не пригадую, щоб заохочувати людей до цього, я чітко згадую про те, що поле та його дані - це дві різні речі. Дякую, що принаймні ви пропонуєте конструктивні відгуки про ваш голос, але я не можу сказати, що це спостереження означає що-небудь у світлі концепції "для чого використовуються негативні ключі", оскільки це проблема логіки програми, а не проблема рівня баз даних . Я хотів висвітлити, як ці речі використовуються в рівні додатків, але в шарі бази даних вони не мають жодного значення.
jcolebrand

1
@JackPDouglas ~ Я використав цей конкретний приклад, оскільки є дуже відомий сайт (мережа сайтів), про який ви, можливо, чули, що робить саме це, тому я не хочу його зневажати, тому що це дійсний "хитрість". Ознайомтеся з цим користувачем dba.stackexchange.com/users/-1/community та скажіть, що таке його посвідчення особи. Я майже можу запевнити вас, що userid є основним (а в багатьох інших таблицях іноземним) ключем. Тільки тому, що це поганий дизайн додатків для вас, не означає, що він недійсний. Але ще раз: це не дизайн db, це дизайн домену. Зрозуміло, логіка db це підтримує
jcolebrand

10

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

Однак, як правило, ви втратите половину свого діапазону, якщо використовуєте підписані цілі числа.
Див.: Що робити, коли поле в таблиці наближається до максимально підписаного чи непідписаного 32-бітного цілого числа?

Інший приклад: у невеликих сценаріях реплікації використання негативних значень для одного сайту та позитивних для іншого дає певні неявні знання про джерело будь-якого рядка.


і переконайтеся, що ви якось обмежуєте введення значень на кожному сайті, інакше ви потрапите в жахливий безлад, коли ваші "неявні знання" виявляться помилковими.
Джек каже, спробуйте topanswers.xyz

@JackPDouglas: ви використовуєте НЕ ДЛЯ ЗАМОВЛЕННЯ, щоб уникнути генерування значень на неправильному сайті
gbn

поряд із обмеженнями перевірки ? Також, чи є аналог MySQL (чи іншого), NOT FOR REPLICATIONякий ви знаєте?
Джек каже, спробуйте topanswers.xyz

@JackPDouglas: вибачте, не впевнений про не-SQL Server
gbn

8

Не всі системи баз даних навіть підтримують цілочисельні типи без підпису, MSSQL є одним із тих, хто цього не робить. У цих випадках від'ємні значення можливі в цілих ключових полях просто тому, що вони можливі в типі (ви можете використовувати правила або тригери для їх блокування, як показано в цьому прикладі , але, мабуть, не потрібно додавати накладні витрати на примусове застосування таких правил до кожен інтерс / оновлення).

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

Непідтримка непідписаних цілочисельних типів, мабуть, є рішенням проекту, заснованим на зменшенні складності, тобто не хоче, щоб два різних 32-бітових цілочисельних типу не турбувалися про перевірку діапазонів при призначенні значень між ними. Це обмежує кількість можливих індексів у полі автоматичного збільшення, починаючи з 0 або 1 до половини, що було б можливим у непідписаному типі (~ 2e9, а не ~ 4e9), але це рідко є суттєвою проблемою (якщо вам, швидше за все, знадобиться ряд ключових значень такої величини ви, ймовірно, все-таки використовували для 64-бітного типу, особливо якщо використовуєте 64-бітну архітектуру, де такі значення обробляються не менш ефективно, ніж 32-розрядні), хоча якщо ви хочете, щоб весь діапазон і потреба були щоб дотримуватися 32-розрядної з космічних причин, ви можете почати приріст на -2,147,483,647.


Так, я думаю, що ми вже накривали цю землю;) tehehe dba.stackexchange.com/questions/983/…
jcolebrand

tinyint не підписаний (0 .. 255). Зазвичай я створюю обмеження для перевірки цілих стовпців, щоб переконатися, що значення не є негативними, оскільки неминуче буде записаний код, який неявно припускає його, і виникнуть дивні помилки, якщо якось негативне значення проступить.
Ed Avis,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.