为什么在PostgreSQL中没有无符号整数?
为什么在PostgreSQL中没有无符号整数?
我看到了这篇帖子(What is the difference between tinyint, smallint, mediumint, bigint and int in MySQL?)并意识到PostgreSQL不支持无符号整数。
有人能帮忙解释一下为什么会这样吗?
在大多数情况下,我在MySQL中使用无符号整数作为自增的主键。在将数据库从MySQL迁移到PostgreSQL时,我该如何克服这个问题?
谢谢。
在PostgreSQL中为什么没有无符号整数?这个问题的出现是因为在PostgreSQL中没有提供无符号整数数据类型。然而,可以通过使用CHECK约束来实现类似的功能。例如,可以在创建表时定义一个CHECK约束来限制整数的取值范围。此外,PostgreSQL还提供了serial、smallserial和bigserial类型,用于自动递增。
需要注意的是,使用CHECK约束的列不能包含NULL值。但是,可以通过在CHECK约束中使用IS NULL或BETWEEN语句来允许NULL值或指定取值范围。然而,这种方法无法提供与无符号整数相同的解决方案,因为无符号整数的取值范围可以达到2^32-1,而有符号整数的取值范围只能达到2^31-1。
另外,需要注意的是,NULL和CHECK是完全独立的概念。可以在使用CHECK约束的列中定义NULL或NOT NULL约束,根据需要选择使用。如果要完全禁止NULL值,则应使用NOT NULL约束。
然而,使用CHECK约束无法实现将IPv4地址存储为整数的需求,因为整数类型无法表示负数。对于这种情况,可能需要考虑使用其他数据类型或自定义解决方案。
总之,尽管PostgreSQL没有提供无符号整数数据类型,但可以通过使用CHECK约束和其他数据类型来实现类似的功能。对于特定需求,可能需要考虑使用其他解决方案或自定义数据类型。
为什么PostgreSQL不提供无符号整数类型?
在PostgreSQL中,为什么没有无符号整数类型已经有人回答过了。然而,我建议使用域来表示无符号类型。
域类似于类型,但具有额外的约束条件。
下面是一个具体的示例:
CREATE DOMAIN uint2 AS int4 CHECK(VALUE >= 0 AND VALUE < 65536);
当我滥用这个类型时,psql会给出以下错误信息:
DS1=# select (346346 :: uint2);
ERROR: value for domain uint2 violates check constraint "uint2_check"
但我猜想,在每次需要无符号列时使用该域会增加插入/更新的开销。最好只在真正需要时使用该域(这种情况很少发生),并且要习惯于数据类型不能满足我们期望的下限的想法。毕竟,它还会设置一个通常在逻辑上没有意义的上限。数值类型并不是为了强制实施我们的应用程序约束而设计的。
这种方法的唯一问题是你“浪费”了15个未使用的数据存储位。更不用说检查操作也会带来一些小的效率损失。更好的解决方案是Postgres将无符号整数作为一种一流类型。在一个有2000万条记录的表中,如果有一个像这样的索引字段,你就浪费了40MB的空间用于未使用的位。如果你在另外20个表中滥用这种类型,你现在就浪费了800MB的空间。
为什么PostgreSQL中没有无符号整数?
在SQL标准中没有定义无符号整数,所以实现这一功能的需求较低。
过多的不同整数类型会使类型解析系统变得更加脆弱,因此对于增加更多类型存在一些抵触情绪。
尽管如此,理论上是可以实现的,只是需要付出大量的工作量。
这个问题很受欢迎,我已经着手解决它:github.com/petere/pguint
在输入/输出转换中使用无符号整数字面量将非常有用,或者甚至只是一个to_char
模式。
这是否也解释了为什么PostgreSQL中没有tinyint(如果我们知道值在范围内,则有时可能更有效)?