Mic*_*ski 3 sql postgresql database-design types constraints
是否可以约束PostgreSQL中整数数据类型列中允许的位数.我有以下示例:
CREATE TABLE bank_accounts (
id SERIAL PRIMARY KEY
, number_account INTEGER(26) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
我们可以输入如下内容:
1 -- one digit
23 -- two digits
444 -- three digits
5555 -- four digits
Run Code Online (Sandbox Code Playgroud)
等等......最多26位数.
但我想我的约束列来存储恰好 26个数字,而不是更少而不是更多.怎么实现呢?
银行帐号本质上不是整数.26个十进制数字是太多integer
还是bigint
反正.
真的,银行帐号根本不是数值,即使我们可以使用该类型numeric
进行存储.它可以轻松处理26位小数.但它也允许小数位(和其他装饰者,如@klin评论).您可以限制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
Run Code Online (Sandbox Code Playgroud)
银行帐号本质上更像是文本,因此数据类型text
似乎更合适(如@klin提供的),即使它在磁盘上占用更多空间(如@a_horse提到的那样).27个字节对17个字节numeric
- 或30个对20个字节的RAM.看到:
但是,您不希望将排序规则应用于银行帐号.出现这种情况与collatable类型,如text
或者varchar
如果你的数据库集群与非C语言环境中运行.只有数字才能开始无效.但是你仍然会得到更慢的排序和更慢的索引等.值得注意的是,Postgres 9.5或更高版本中的"缩写键"功能目前(包括Postgres 10)已禁用非C语言环境.
把所有东西放在一起,我建议:
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}$')
);
Run Code Online (Sandbox Code Playgroud)
旁白:
考虑一个IDENTITY
列而不是serial
Postgres 10+中的in.细节:
在Postgres中是无效的语法,其中INTEGER(26)
integer
数据类型没有修饰符.您可以选择int2
,int4
(默认integer
)int8
,但是 - 悬挂数字表示占用的字节,而不是允许的位数.