是否可以约束PostgreSQL中整数数据类型列中允许的位数。我有以下示例:
CREATE TABLE bank_accounts (
id SERIAL PRIMARY KEY
, number_account INTEGER(26) NOT NULL
);
我们可以输入类似的内容:
1 -- one digit
23 -- two digits
444 -- three digits
5555 -- four digits
等。 ......最多26位数。
但是我想限制我的列存储完全 26位数,而不是更少而不是更多。如何实现?
答案 0 :(得分:6)
银行帐号本质上是不是整数。无论如何,integer
or bigint
的26个十进制数字太多了。
银行帐号根本不是数值,实际上,即使我们可以使用类型numeric
进行存储。它可以轻松处理26位小数。但它也允许小数位(和其他装饰器,like @klin commented)。您可以将numeric(26)
限制为numeric(26,0)
的缩写,以便从存储中删除小数位数。但是仍然允许输入的小数位数,然后四舍五入。和其他装饰者。所有这些似乎都不适合银行帐号:
SELECT numeric(26) '12345678901234567890123456'
, numeric(26) '12345678901234567890123456.4' -- rounded down
, numeric(26) '12345678901234567890123456.5' -- rounded up
, numeric(26) '1e25'
, numeric(26) '1.2345e25'
, numeric(26) '+12345678901234567890123456.5'
SELECT numeric(26) '99999999999999999999999999.5' -- error after rounding up
银行帐号本身更像文字,因此数据类型text
似乎更合适(like @klin provided),即使在磁盘上占用更多空间(like @a_horse mentioned)。 numeric
为27字节对17字节 - 或RAM为30对20字节。参见:
但是,您不希望将collation rules应用于银行帐号。如果您的数据库集群使用非C语言环境运行,则会发生类似text
或varchar
等可整理类型的情况。只有数字才能开始无效。但是你仍然会得到更慢的排序和更慢的索引等。值得注意的是,Postgres 9.5或更高版本中的"abbreviated keys" feature目前(包括Postgres 10)disabled for non-C locales。
把所有东西放在一起,我建议:
CREATE TABLE bank_account (
bank_account_id serial PRIMARY KEY
-- bank_account_id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY -- in Postgres 10+
, number_account text COLLATE "C" NOT NULL -- disable collation rules
, CONSTRAINT number_account_has_26_digits CHECK (number_account ~ '^\d{26}$')
);
旁白:
在Postgres 10+中考虑使用IDENTITY
列而不是serial
。详细说明:
在Postgres中的语法无效,其中INTEGER(26)
integer
data type没有修饰符。您可以选择int2
,int4
(默认integer
)和int8
- 悬挂数字表示占用的字节数,而不是允许的位数。
答案 1 :(得分:1)
The maximum integer value是2147483647,最大bigint是9223372036854775807.您不能对列使用整数类型。
似乎最简单的方法是使用检查约束将列定义为文本:
CREATE TABLE bank_accounts (
id serial primary key,
number_account text not null check (number_account ~ '^\d{26}$')
);
检查约束中使用的正则表达式表示a string with exactly 26 digits
。