我想用自己定制的id生成器替换我在postgresql数据库中用于id的一些序列。生成器将生成一个随机数,最后带有一个校验位。所以这:
SELECT nextval('customers')
将被这样的东西代替:
SELECT get_new_rand_id('customer')
然后,该函数将返回一个数字值,例如:[1-9][0-9]{9}其中最后一位是校验和。
[1-9][0-9]{9}
我担心的是:
注意1 :我不想使用uuid,因为它可以与客户进行通信,并且10位数字比36字符的uuid更容易通信。
注意2 :该函数很少用调用,SELECT get_new_rand_id()而是在id列而不是上被指定为默认值nextval()。
SELECT get_new_rand_id()
nextval()
编辑 :好的,下面很好的讨论!以下是有关 原因的 一些解释:
我给每个新客户一个唯一的customerId(数据库中生成的序列号)。由于我要与客户沟通该号码,因此竞争对手要监视我的业务是一项相当简单的任务(还有其他具有相同属性的号码,例如发票编号和订单编号)。我想使这种监视更加困难(注意:不是不可能,而是更加困难)。
在谈论隐藏序列号nr之前,我在ordernr中添加了一个校验位,因为在生产中的某些时候手指有些笨拙,而且我认为这是将来保留的好习惯。
在阅读讨论之后,我当然可以看到我的方法不是解决问题的最佳方法,但是我对解决问题没有其他好主意,所以请在这里帮助我。
为了从序列中生成唯一且具有随机外观的标识符,使用密码可能是一个好主意。由于它们的输出是双射的(输入和输出值之间存在一对一的映射)-与哈希不同,您 不会有任何冲突 。这意味着您的标识符不必像哈希一样长。
大多数加密密码都可以在64位或更大的块上运行,但是PostgreSQL Wiki上有一个示例PL / pgSQL过程,用于“非加密”密码功能,该功能适用于(32位)int类型。免责声明:我尚未尝试使用此功能。
int
要将其用于主键,请从Wiki页面运行CREATE FUNCTION调用,然后在 空 表上执行以下操作:
ALTER TABLE foo ALTER COLUMN foo_id SET DEFAULT pseudo_encrypt(nextval('foo_foo_id_seq')::int);
瞧!
pg=> insert into foo (foo_id) values(default); pg=> insert into foo (foo_id) values(default); pg=> insert into foo (foo_id) values(default); pg=> select * from foo; foo_id ------------ 1241588087 1500453386 1755259484 (4 rows)