为啥 PostgreSQL 不使用无符号整数作为 ID?那不会提供两倍的可能记录吗?

Posted

技术标签:

【中文标题】为啥 PostgreSQL 不使用无符号整数作为 ID?那不会提供两倍的可能记录吗?【英文标题】:Why doesn't PostgreSQL use unsigned integers for IDs? Wouldn't that give twice as many possible records?为什么 PostgreSQL 不使用无符号整数作为 ID?那不会提供两倍的可能记录吗? 【发布时间】:2019-06-17 15:08:12 【问题描述】:

根据this documentation,PostgreSQL 不支持无符号整数。

虽然我知道它使类型解析系统不那么复杂,但我不明白这对于自动递增 ID 来说有什么实际意义。

添加一个无符号整数作为自动增量 ID 不会导致使用常规 int 的可能记录数量增加两倍吗? (4294967296 而不是2147483648

我知道它只是表示 1 位之间的差异,但它仍然是你永远不会使用的位。

谢谢!

【问题讨论】:

如果您需要完整范围,请使用否定 ID。没问题。 serial 是(实际上)一个将自动递增起点设置为 1 的宏,但您可以建立自己的序列并指定起点。请参阅之前的答案:***.com/a/13187557/2067753 【参考方案1】:

按照惯例,ID 是从 1 开始的正整数(据我所知,这不是由标准强制执行的,但如果是这样的话也不会完全令人惊讶)。 PostgreSQL serial 数据类型实现了这个约定,并且值也是“自动生成的”。

如果你真的想实现自己的方法,你可以这样做:

create sequence epictable_seq
    MINVALUE -2147483648 
    start -2147483648 
    increment 1
    NO MAXVALUE
    CACHE 1;
CREATE TABLE epictable
(
    mytable_key    INT unique not null,
    moobars        VARCHAR(40) not null,
    foobars        DATE
);
insert into epictable(mytable_key, moobars,foobars) 
values
  (nextval('epictable_seq'),'delicious moobars','2012-05-01')
, (nextval('epictable_seq'),'worldwide interblag','2012-05-02')
;
2 行受影响
select * 
from epictable
;
mytable_key |穆巴 |吧台 ----------: | :----------------- | :--------- -2147483648 |美味的moobar | 2012-05-01 -2147483647 |全球interblag | 2012-05-02

db小提琴here

另见this former answer

【讨论】:

感谢您的回复,但我想知道为什么会这样,而不是如何解决。我目前对我获得的记录数量没有问题,如果我这样做了,我只会切换到 64 位整数。我只是好奇这背后的思考过程是什么。 “从 1 开始”。正如我所说,我相信这只是“按照惯例”。我相信这源于我们学习计数的方式,当我们实际上可以看到一些东西来计数时,因此我们的计数心理模型通常从 1 开始。 @PeterWillemsen 另外,如果您担心 4 字节整数可能会用完正值,您可以使用 bigserial。我想这些天很少有人介意浪费 4 个字节。如果有人是的话,将无符号整数数据类型添加到 PostgreSQL 中并不难,因为它是可扩展的。 @LaurenzAlbe 不是也签名了 bigserial 吗?但是,是的,我明白你的意思 啊,也许我现在明白你问题的重点了。我不知道任何支持无符号整数的 RDBMS(虽然我不知道那里的每个 rdbms)。由于任何数字数据类型都可以在计算中使用,我怀疑它过于严格而不能只允许正数。

以上是关于为啥 PostgreSQL 不使用无符号整数作为 ID?那不会提供两倍的可能记录吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C 没有无符号浮点数?

为啥 SQL Server 不支持无符号数据类型?

为啥 unsigned int 不符合 CLS?

Oracle 数据库无符号整数

为啥使用 MSB 作为符号位?

有符号整数与无符号整数