Почему SQL Server не поддерживает беззнаковый тип данных?

Я специально думаю о неподписанном int.

Вот практический пример: что вы делаете, когда ваш столбец идентичности достигает максимума? Можно либо пойти BigInt (хранилище 8 байтов вместо 4), либо провести рефакторинг приложения для поддержки отрицательных целых чисел и даже создать свои собственные правила, как указано в этот ответ; ни один из этих вариантов не является оптимальным.

UInt было бы идеальным решением, но SQL Server не предлагает его (в отличие от MySQL).

Я понимаю, что беззнаковые типы данных не являются частью стандарта SQL (SQL-2003), но все же мне кажутся пустой тратой.

По какой причине они не включены (в SQL Server или в стандарт)?


person Romhein    schedule 15.12.2010    source источник
comment
Спросите команду разработчиков SQL Server ... также: вы действительно собираетесь максимально использовать даже 2 МИЛЛИАРДА значений INT IDENTITY ?? ДЕЙСТВИТЕЛЬНО?!?!?! Если у вас более 2 миллиардов строк того, с чем вы имеете дело, держу пари, вы можете сэкономить немного места на диске и использовать BIGINT в качестве ИДЕНТИФИКАЦИИ ....   -  person marc_s    schedule 15.12.2010
comment
Что вы имеете в виду marc_s? Это только вставка каждые 800 мс в течение 50 лет подряд, у ваших таблиц нет такой активности? :)   -  person Mike M.    schedule 15.12.2010
comment
@Mike M: Не все из нас работают над приложениями с Микки Маусом ... мы использовали более 3 миллиардов bigint менее чем за 2 года. Пиковая скорость ›2000 строк в секунду.   -  person gbn    schedule 15.12.2010
comment
@gbn Я не имел в виду, что ни у кого не было этой нагрузки. Однако, как уже было сказано, если у вас ДЕЙСТВИТЕЛЬНО ›2000 строк в секунду, дополнительные 2Б вам не помогут.   -  person Mike M.    schedule 15.12.2010
comment
@marc_s, верно… Давайте избегать любых вопросов, связанных с дизайном, по SO. В конце концов, у команды, создавшей продукт, наверняка есть ответ. Я слышал, что вы говорите о количестве значений, но мой вопрос не касался выбора правильного типа данных; это было дано только в качестве примера. Спасибо, что нашли время добавить красивое форматирование к вашему комментарию, это приветствуется.   -  person Romhein    schedule 16.12.2010
comment
@Mike M и @marc_s, если бы я работал в системе с таблицей с 2 ​​миллиардами строк, я мог бы обратить внимание на потраченное впустую хранилище. Я могу обратить внимание на размер страницы индекса и скорость сканирования индекса. В таких условиях хотелось бы не тратить место зря.   -  person Romhein    schedule 16.12.2010
comment
@Nip: Я за то, чтобы задавать вопросы, связанные с дизайном, но часто постороннему невозможно узнать, какие аргументы или мысли стоят за определенным решением. Это все....   -  person marc_s    schedule 17.12.2010
comment
Почему отрицательные значения идентичности должны быть проблемой для вашего приложения? Каким образом отрицательные значения идентичности субоптимальны?   -  person onedaywhen    schedule 09.01.2012
comment
Просто для того, чтобы на секунду поиграть в авокадо дьявола - использование uint вместо int может быть полезно для указания intent в отношении свойства объекта. Например, вы не хотите размещать заказ с отрицательным количеством или записывать транзакцию с отрицательной суммой (распространенная ошибка). Дело не всегда в возможности достичь более высокого максимального значения.   -  person Neil Barnwell    schedule 28.01.2016
comment
@marc_s, int может использоваться не только для хранения большого числа, но и для других целей. Поле битовой маски не должно храниться в подписанном int, или, как говорит Нил Барнуэлл, в этом случае ваше намерение не отображается при наличии подписанного int, и вам, вероятно, не следует использовать крайний левый бит. Есть и другие случаи, и это зависит от данных, которые вы храните.   -  person astrosteve    schedule 23.03.2016
comment
Моя база данных больше: p   -  person Chili Con Code    schedule 28.06.2019
comment
Для справки, у моей компании (очень большого банка) есть производственная база данных журналов Splunk, которая накапливает более 380 миллиардов строк данных в год (скользящий размер, один год всегда в сети).   -  person McGuireV10    schedule 25.09.2020


Ответы (6)


Если бы мне пришлось угадывать, я бы сказал, что они пытаются избежать размножения типов. Вообще говоря, нет ничего, что могло бы сделать целое число без знака, чего не могло бы сделать целое число со знаком. Что касается случая, когда вам нужно число от 2147483648 до 4294967296, вам, вероятно, следует перейти к 8-байтовому целому числу, поскольку это число также в конечном итоге превысит 4294967296.

person Jeff Hornby    schedule 15.12.2010
comment
Думаю, это наиболее близкий ответ на этот вопрос. Спасибо. - person Romhein; 10.02.2011
comment
Если «распространение типов» могло сэкономить место / деньги, почему вы думаете, что это могло быть злом. - person Samuel; 17.07.2013
comment
Получение строк по их значению также будет медленнее (т. Е. ORDER BY ABS(Id)), особенно если столбец является кластеризованным первичным ключом. Например, использование 32-битной временной метки unix часто является удобным способом сократить 4 байта стандартной даты и времени SQL. - person Groo; 31.10.2014

Для этой цели вы можете использовать -2 147 483 648 в качестве начального значения.

Identity(-2147483648, 1)
person CFreitas    schedule 09.01.2012
comment
Ха, мне очень нравится этот ответ. Я не уверен, что когда-нибудь реализовал бы это, но это определенно решило проблему неиспользования половины ваших идентификаторов. - person Kevin; 08.12.2020
comment
хорошее решение ... не очень ... но решает проблему ... используя min_value как ноль (0) ... эффективно используя шкалу Кельвина;) - person GoldBishop; 18.03.2021

Я нашел похожий вопрос в Центре разработки Microsoft Office.

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

Запрос был закрыт как «Не исправить».

person Anthony K    schedule 08.08.2013
comment
Ссылка больше не работает, поэтому я не могу прочитать исходный ответ. Но я считаю, что проблема не в том, что это кошмар; дело в том, что нет стандарта, который говорит, как это делать. Например, они могут делать то, что делает MySQL (я не думаю, что другие СУБД поддерживают UNSIGNED), но если другая СУБД добавляет поддержку знаков, они могут использовать другие правила. Дизайн конверсии - важный вопрос. JavaScript - это пример того, что происходит, когда к нему не относятся всерьез. - person Federico Razzoli; 06.02.2020
comment
Обновленная ссылка - комментарий Джима Хогга на форуме разработчиков MSSN Office. - person Anthony K; 06.02.2020
comment
Мне очень нужны беззнаковые целочисленные типы, потому что они более точно отражают характер хранимых данных. Я полностью понимаю опасения по поводу неявного преобразования, но это не должно быть проблемой, потому что неявное преобразование в любого беззнакового типа из подписанного типа не должно быть разрешено - что аккуратно решает это проблема (я предполагаю, что этого требует ISO SQL?). В конечном итоге меня разочаровывает то, что нам как разработчикам приложений говорят моделировать наши данные как можно ближе к бизнес-области, но затем мы оказываемся в затруднительном положении из-за наших инструментов, которые не позволяют нам это делать. - person Dai; 20.02.2021

Они не поддерживают ключевые слова SIGNED и UNSIGNED, потому что они нестандартны. В стандарте SQL все числовые типы подписаны.

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

person Federico Razzoli    schedule 17.12.2019
comment
В стандарте SQL все числовые типы подписаны - да, но ISO SQL болезненно противоречит повседневным задачам моделирования данных и разработки приложений. Становится абсолютной необходимостью нарушить спецификацию ISO SQL, чтобы предоставить что-то пригодное для использования. - person Dai; 20.02.2021
comment
НЕПОДПИСАННЫЕ типы желательны, но не так важны. Большинство СУБД их не поддерживают, что значительно упрощает преобразование типов (и, следовательно, операции между разными типами). Если вы хотите избежать отрицательных чисел, добавьте ограничение CHECK. - person Federico Razzoli; 20.02.2021

Возьмем, например, 32-битное (8-байтовое) int. Диапазон 32-битного int составляет от -2 ^ 31 до 2 ^ 31-1. Для записи назначенного вами значения требуется 31 бит и только 1 бит для записи знака значения.

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

person Ian    schedule 06.04.2021

Установите для своей БД минимальную идентичность Identity (-2147483648, 1)

Затем при загрузке в вашу переменную .net UInt64 добавьте к ней 2147483648. тогда -2147483648 становится 0 -1000000000 становится 1147483648

  • Но также в большинстве случаев внутренние ключи не должны быть открыты клиентам, я обычно использую отдельный ключ, который может быть чем угодно вроде 'ABCKey1

Однако я согласен с тем, что тип данных достаточно велик в 99% существующих систем. Если вам действительно нужно больше, вы можете использовать GUID - однако это отстой для Index, если вы не используете следующий последовательный GUID.

person Brian Clark    schedule 23.04.2021