Adr*_*Hoe 98 postgresql unsigned-integer
我遇到过这篇文章(在MySQL中,tinyint,smallint,mediumint,bigint和int之间的区别是什么?)并且意识到PostgreSQL不支持无符号整数.
任何人都可以帮忙解释为什么会如此?
大多数时候,我使用无符号整数作为MySQL中的自动递增主键.在这样的设计中,当我将数据库从MySQL移植到PostgreSQL时,如何克服这个问题呢?
谢谢.
Pet*_*aut 74
它不符合SQL标准,因此实现它的一般要求较低.
具有太多不同的整数类型会使类型分辨率系统更加脆弱,因此在混合中添加更多类型会有一些阻力.
也就是说,没有理由不能这样做.这只是很多工作.
小智 38
已经回答了postgresql缺少无符号类型的原因.但是,我建议将域用于无符号类型.
http://www.postgresql.org/docs/9.4/static/sql-createdomain.html
CREATE DOMAIN name [ AS ] data_type
[ COLLATE collation ]
[ DEFAULT expression ]
[ constraint [ ... ] ]
where constraint is:
[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }
Run Code Online (Sandbox Code Playgroud)
域就像一个类型,但有一个额外的约束.
您可以使用具体示例
CREATE DOMAIN uint2 AS int4
CHECK(VALUE >= 0 AND VALUE < 65536);
Run Code Online (Sandbox Code Playgroud)
这是我尝试滥用类型时psql给出的内容.
DS1 = #select(346346 :: uint2);
错误:域uint2的值违反了检查约束"uint2_check"
Tri*_*Man 30
您可以使用CHECK约束,例如:
CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0)
);
Run Code Online (Sandbox Code Playgroud)
PostgreSQL也有自动增量smallserial
和serial
类型.
Gun*_*dow 15
关于 DOMAINS 的讨论很有趣,但与该问题的唯一可能来源无关。无符号整数的愿望是将具有相同位数的整数范围加倍,这是一个效率参数,而不是排除负数的愿望,每个人都知道如何添加检查约束。
当有人问起此事时,Tome Lane 说:
基本上,这种情况发生的可能性为零,除非您能找到一种方法将它们放入不会破坏许多现有应用程序的数字提升层次结构中。如果没记错的话,我们已经不止一次地研究过这个问题,但未能提出一个似乎没有违反 POLA 的可行设计。
什么是“POLA”?Google 给了我 10 个毫无意义的结果。不确定这是否是政治上不正确的想法,因此被审查。为什么这个搜索词不会产生任何结果?任何。
您可以将无符号整数实现为扩展类型而不会太麻烦。如果你用 C 函数来做,那么根本不会有性能损失。您不需要扩展解析器来处理文字,因为 PgSQL 有一种将字符串解释为文字的简单方法,只需将 '4294966272'::uint4 写为您的文字。演员也不应该是一个大问题。您甚至不需要进行范围异常,您只需将 '4294966273'::uint4::int 的语义视为 -1024。或者你可以抛出一个错误。
如果我想要这个,我会做到的。但是因为我在 SQL 的另一边使用 Java,对我来说它没有什么价值,因为 Java 也没有那些无符号整数。所以我一无所获。如果我从 bigint 列中得到一个 BigInteger,而当它应该适合 long 时,我已经很生气了。
另一件事,如果我确实需要存储 32 位或 64 位类型,我可以分别使用 PostgreSQL int4 或 int8,只要记住自然顺序或算术不会可靠地工作。但是存储和检索不受此影响。
下面是我如何实现一个简单的 unsigned int8:
首先我会用
CREATE TYPE name (
INPUT = uint8_in,
OUTPUT = uint8_out
[, RECEIVE = uint8_receive ]
[, SEND = uint8_send ]
[, ANALYZE = uint8_analyze ]
, INTERNALLENGTH = 8
, PASSEDBYVALUE ]
, ALIGNMENT = 8
, STORAGE = plain
, CATEGORY = N
, PREFERRED = false
, DEFAULT = null
)
Run Code Online (Sandbox Code Playgroud)
最小的 2 个函数uint8_in
,uint8_out
我必须首先定义。
CREATE FUNCTION uint8_in(cstring)
RETURNS uint8
AS 'uint8_funcs'
LANGUAGE C IMMUTABLE STRICT;
CREATE FUNCTION uint64_out(complex)
RETURNS cstring
AS 'uint8_funcs'
LANGUAGE C IMMUTABLE STRICT;
Run Code Online (Sandbox Code Playgroud)
需要在 C uint8_funcs.c 中实现它。所以我使用这里的复杂示例并使其变得简单:
PG_FUNCTION_INFO_V1(complex_in);
Datum complex_in(PG_FUNCTION_ARGS) {
char *str = PG_GETARG_CSTRING(0);
uint64_t result;
if(sscanf(str, "%llx" , &result) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for uint8: \"%s\"", str)));
return (Datum)SET_8_BYTES(result);
}
Run Code Online (Sandbox Code Playgroud)
嗯,或者你可以发现它已经完成了。
归档时间: |
|
查看次数: |
51057 次 |
最近记录: |