Я наткнулся на этот пост (В чем разница между tinyint, smallint, mediumint, bigint и int в MySQL? ) И понял, что PostgreSQL не поддерживает целые числа без знака.
Может ли кто-нибудь помочь объяснить, почему это так?
В большинстве случаев я использую целое число без знака в качестве автоматически увеличивающегося первичного ключа в MySQL. Как я могу решить эту проблему при таком дизайне при переносе базы данных с MySQL на PostgreSQL?
Спасибо.
postgresql
unsigned-integer
Адриан Хоу
источник
источник
serial
(от 1 до 2147483647) илиbigserial
(от 1 до 9223372036854775807). 64-битное целое число со знаком, вероятно, предлагает более чем достаточно места.Ответы:
Уже есть ответ, почему postgresql не хватает беззнаковых типов. Однако я бы предложил использовать домены для беззнаковых типов.
http://www.postgresql.org/docs/9.4/static/sql-createdomain.html
Домен похож на тип, но с дополнительным ограничением.
Для конкретного примера вы можете использовать
Вот что дает psql, когда я пытаюсь злоупотребить типом.
источник
Его нет в стандарте SQL, поэтому общая потребность в его реализации ниже.
Наличие слишком большого количества различных целочисленных типов делает систему разрешения типов более хрупкой, поэтому есть некоторое сопротивление добавлению большего количества типов в смесь.
Тем не менее, нет никаких причин, по которым этого нельзя было бы сделать. Это просто большая работа.
источник
to_char
выкройка.Вы можете использовать ограничение CHECK, например:
Кроме того , PostgreSQL имеет
smallserial
,serial
иbigserial
типов для автоматического увеличения.источник
2^32-1
возрасти до , а подписанные int могут подняться до2^31-1
.NULL
иCHECK
полностью ортогональны. Вы можете иметьNULL
/NOT NULL
столбцы с или безCHECK
. Просто обратите внимание, что, согласно документации на postgresql.org/docs/9.4/ddl-constraints.html ,CHECK
возврат NULL оценивается как TRUE, поэтому, если вы действительно хотите предотвратить NULL, используйтеNOT NULL
вместо него (или в дополнение кCHECK
).integer
(по крайней мере, без случайного положительного или отрицательного значения ...)Разговор о DOMAINS интересен, но не имеет отношения к единственно возможному источнику этого вопроса. Желание беззнаковых целых чисел состоит в том, чтобы удвоить диапазон целых чисел с тем же количеством битов, это аргумент эффективности, а не желание исключить отрицательные числа, каждый знает, как добавить ограничение проверки.
Когда кто-то спросил об этом , Том Лейн сказал:
Что такое «ПОЛА»? Google дал мне 10 результатов, которые не имеют смысла . Не уверен, что это политически некорректная мысль и поэтому подвергается цензуре. Почему этот поисковый запрос не даст никакого результата? Без разницы.
Вы можете без особых проблем реализовать беззнаковые целые числа как типы расширения. Если вы сделаете это с помощью C-функций, то вообще не будет никаких штрафов за производительность. Вам не нужно расширять синтаксический анализатор для работы с литералами, потому что PgSQL имеет такой простой способ интерпретировать строки как литералы, просто напишите '4294966272' :: uint4 в качестве литералов. Броски тоже не должны иметь большого значения. Вам даже не нужно делать исключения диапазона, вы можете просто обработать семантику '4294966273' :: uint4 :: int как -1024. Или можете выдать ошибку.
Если бы я этого хотел, я бы это сделал. Но поскольку я использую Java на другой стороне SQL, для меня это не имеет большого значения, поскольку в Java нет этих целых чисел без знака. Так что я ничего не получаю. Меня уже раздражает, если я получаю BigInteger из столбца bigint, когда он должен уместиться в long.
Другое дело, если бы мне действительно нужно было хранить 32-битные или 64-битные типы, я мог бы использовать PostgreSQL int4 или int8 соответственно, просто помня, что естественный порядок или арифметика не будут работать надежно. Но на хранение и извлечение это не влияет.
Вот как я могу реализовать простой беззнаковый int8:
Сначала я буду использовать
минимальные 2 функции,
uint8_in
иuint8_out
я должен сначала определить.необходимо реализовать это в C uint8_funcs.c. Итак, я использую сложный пример отсюда и упрощаю его:
ну ладно, или ты можешь просто найти это уже готовым .
источник
Согласно последней документации, единственное целое число поддерживается, но в таблице нет целого числа без знака. Однако серийный тип похож на беззнаковый, за исключением того, что он начинается с 1, а не с нуля. Но верхняя граница такая же, как у опаленной. Так что у системы действительно нет поддержки без подписи. Как указал Питер, открыта дверь для реализации неподписанной версии. Код, возможно, придется много обновлять, просто слишком много работы из моего опыта работы с программированием на C.
https://www.postgresql.org/docs/10/datatype-numeric.html
источник
Postgres имеет беззнаковое целое число типа, которое неведомо многим:
OID
.Однако это не числовой тип , и попытка выполнить с ним какие-либо арифметические операции (или даже побитовые операции) потерпит неудачу. Кроме того, это всего лишь 4 байта (
INTEGER
), нет соответствующего 8-байтового (BIGINT
) беззнакового типа.Так что использовать это самостоятельно не очень хорошая идея, и я согласен со всеми другими ответами, что в дизайне базы данных Postgresql вы всегда должны использовать столбец
INTEGER
илиBIGINT
для своего серийного первичного ключа - чтобы он начинался с отрицательного (MINVALUE
) или разрешал его to wrap around (CYCLE
), если вы хотите исчерпать весь домен.Однако он очень полезен для преобразования ввода / вывода, например, при переходе с другой СУБД. Вставка значения
2147483648
в целочисленный столбец приведет к ошибке « ОШИБКА: целое число вне допустимого диапазона », в то время как использование выражения2147483648::OID
работает нормально.Точно так же при выборе целочисленного столбца в качестве текста с помощью
mycolumn::TEXT
вы в какой-то момент получите отрицательные значения, но сmycolumn::OID::TEXT
вы всегда получите натуральное число.См. Пример на dbfiddle.uk .
источник