如何指定银行帐号的最小和最大位数?

时间:2017-10-22 11:24:33

标签: sql postgresql database-design types constraints

是否可以约束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位数,而不是更少而不是更多。如何实现?

2 个答案:

答案 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语言环境运行,则会发生类似textvarchar等可整理类型的情况。只有数字才能开始无效。但是你仍然会得到更慢的排序和更慢的索引等。值得注意的是,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}$')
);

旁白:

答案 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