在PostgreSQL中,用于引用SERIAL数据类型的数据类型是什么?

9

我在PostgreSQL中有两个表。第一个表应该有一个自增的ID字段,第二个表引用它:

CREATE TABLE tableA (id SERIAL NOT NULL PRIMARY KEY, ...)
CREATE TABLE tableB (parent INTEGER NOT NULL REFERENCES tableA(id), ...)

根据文档SERIAL 表示无符号4字节整数,而 INTEGER 则表示有符号整数:
serial      4 bytes     autoincrementing integer    1 to 2147483647
integer     4 bytes     typical choice for integer  -2147483648 to +2147483647

如果我理解正确,我使用的数据类型不兼容,但是PostgreSQL显然缺少无符号整数。我知道我可能不会使用超过2*10^9个ID(如果我这样做了,我可以随时使用BIGSERIAL),而且这并不是很重要,但是对我来说,有符号整数引用无符号整数似乎有点不干净。我相信一定有更好的方法 - 我错过了什么吗?


有一个扩展可以处理无符号整数: https://github.com/petere/pguint - 它在你链接的问题中被引用。 - Aleks G
是的,我知道,谢谢 - 但虽然我更喜欢PostgreSQL支持无符号整数,但这对我来说并不是那么重要。在我的情况下,使用扩展似乎有些过度(我不知道扩展代码的成熟度,它会引入额外的部署约束,并可能导致与核心psql等类似的未来兼容性问题)。 - johndodo
1个回答

14
一个序列(Serial)是一个整数,并且它不是“无符号(unsigned)”的。自动创建的序列只是从1开始而已——这就是全部。该列的数据类型仍然是一个整数(Integer),如果你想的话,可以让序列从-2147483648开始。

来自手册的引用

CREATE TABLE tablename (
    colname SERIAL
);

等价于 equivalent

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
(emphasis mine)

啊...我现在明白我的错误了。当我看到SERIAL1开始时,我误读了结束值为410^9,而不是210^9...但实际上,SERIAL值只是INTEGER值的一个子集。现在这有意义了,谢谢! - johndodo
@johndodo:不,它不是一个“子集”。它与integer完全相同。在psql中使用\d查看表定义,你会发现它是一样的。 - user330315
同意,serial 不是 integer 的子集 - 但是 serial values (1 到 2147483647) integer values (-2147483648 到 2147483647) 的子集。如果我在这里没有使用精确的数学术语,那么很抱歉 - 英语不是我的母语。但我完全理解你的意思,只是我的错误出在其他地方,你的答案帮助我找到了它。所以谢谢! - johndodo
1
正如我已经写过的那样:如果您愿意,序列值可以从-2147483648开始。 - user330315

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接