Для чего используются отрицательные ключи?

12

Несколько нововведенный в использовании стандартных баз данных SQL (в настоящее время в основном работающих с MySQL), я еще не сталкивался с этим во многих случаях.

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

Гарет Клаборн
источник
5
Во-первых, кто бы ни отрицал, не оставляя обратной связи, вы оказываете медвежью услугу. Далее ответ на этот отличный вопрос.
Jcolebrand
1
Этот предмет интригует. Я лично никогда не слышал об этой концепции. Этот вопрос никогда не должен был опускаться. +1 от меня за представление этой концепции.
RolandoMySQLDBA

Ответы:

13

Все первичные ключи - это значение, которое мы определили, это значение, которое имеет первостепенное значение в записи. Является ли этот ключ подписанным int, неподписанным int, строкой, большим двоичным объектом (на самом деле, существуют ограничения) или UUID (или каким-либо другим именем, которое он принимает сегодня), факт остается фактом, что это ключ и что он является вещь первостепенной важности.

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

Что касается того, почему было бы полезно иметь «отрицательные ключи» в таблице, это тот же вопрос, что и «почему полезно иметь ключи в таблице». «Значение» ключа не влияет на его статус в качестве ключа. Ключ это ключ это ключ.

Что важно, так это если ключ действителен.

Что касается того, почему было бы полезно разрешить ключи, которые были отрицательными, я могу предложить несколько причин:

Что если вы хотите указать возврат в системе продаж в виде отрицательных номеров заказа на продажу, которые соответствуют положительному номеру заказа на продажу, что облегчает корреляцию (это наивно и плохо спроектировано, но будет работать в смысле «электронных таблиц»).

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

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

Jcolebrand
источник
Отредактировал бит «нишевое происшествие», так как это скорее всего недоразумение из-за неопытности. Интересно читать. Я несколько воображал, что будет ситуация, когда отрицательное значение ключа будет каким-то образом полезно для кодирования (т. Е. Без принятия решения означает, что это определенная вещь), но это очень полезное мышление, когда у вас сильное деление на две группы и не хочу использовать лишний bool: p
Garet Claborn
1
@Garet ~ Итак, вы делаете хорошее замечание: «значение ключа было как-то полезно при кодировании», и я время от времени использую свои ключи именно таким образом, но это не имеет никакого отношения к аспекту базы данных. База данных является хранилищем. Приложение, которое потребляет данные, с другой стороны, заботится о значениях . Но да, этот логический +/- это хитрый трюк, я видел, что он использовал много раз именно для такого эффекта.
Jcolebrand
2
-1 для намека на то, что двойные целевые значения, подобные этому, не являются плохой идеей. Вам нужен int и bool? Используйте int и bool.
Джек говорит, попробуйте topanswers.xyz
1
@JackPDouglas Я не помню, чтобы люди поощряли это делать, я строго напоминаю, что поле и его данные - это две разные вещи. Спасибо, по крайней мере, за конструктивную обратную связь с вашим отрицательным голосом, но я не могу сказать, что это наблюдение означает что-либо в свете концепции «для чего используются отрицательные ключи», поскольку это проблема логики приложения, а не проблема уровня базы данных , Я хотел подчеркнуть, как эти вещи используются на прикладном уровне, но на уровне базы данных они не имеют никакого значения.
Jcolebrand
1
@JackPDouglas ~ Я использовал этот конкретный пример, потому что есть очень хорошо известный сайт (сеть сайтов), о котором вы, возможно, слышали, который делает именно эту вещь, поэтому я не хочу отрицать это, потому что это действительный «трюк». Проверьте этого пользователя dba.stackexchange.com/users/-1/community и скажите мне его идентификатор. Я могу почти заверить вас, что идентификатор пользователя является первичным (а во многих других таблицах внешним) ключом. То, что для вас плохой дизайн приложения, не означает, что оно недействительно. Но опять же, это не дизайн БД, это дизайн домена. Конечно, логика БД это поддерживает
jcolebrand
10

Если мы говорим о столбцах идентификаторов или автономных номеров, само значение не должно иметь никакого значения. (иногда так и происходит, согласно сообщениям пользователей чата SO, представленных drachenstern, что я и сделал раньше)

Однако, как правило, вы потеряете половину своего диапазона, если используете целые числа со знаком.
См .: Что делать, когда поле в таблице приближается к максимальному 32-разрядному целому числу со знаком или без знака?

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

ГБН
источник
и убедитесь, что вы каким-то образом ограничиваете ввод значений на каждом сайте, иначе вы окажетесь в ужасном беспорядке, когда ваши «скрытые знания» окажутся неправильными.
Джек говорит, что попробуйте topanswers.xyz
@JackPDouglas: вы бы использовали NOT FOR REPLICATION, чтобы избежать создания значений на неправильном сайте
gbn
наряду с проверочными ограничениями ? Кроме того, есть ли MySQL (или другой) аналог того, NOT FOR REPLICATIONчто вы знаете?
Джек говорит, что попробуйте topanswers.xyz
@JackPDouglas: извините, не уверен насчет не SQL Server
gbn
8

Не все системы баз данных даже поддерживают целочисленные типы без знака, MSSQL - один из тех, которые этого не делают. В этих случаях отрицательные значения возможны в полях целочисленных ключей просто потому, что они возможны в типе (вы можете использовать правила или триггеры, чтобы заблокировать их, как показано в этом примере , но, вероятно, нет необходимости добавлять накладные расходы на применение таких правил к каждые inters / update).

Что касается базы данных, то фактическое значение первичного ключа не имеет значения, если оно уникально в таблице. Для него -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