Ulf*_*lfR 12 sql random postgresql
我想用我自己定制的id生成器替换我在postgresql数据库中用于id的一些序列.生成器将生成一个随机数,最后带有一个checkdigit.所以这:
SELECT nextval('customers')
Run Code Online (Sandbox Code Playgroud)
会被这样的东西取代:
SELECT get_new_rand_id('customer')
Run Code Online (Sandbox Code Playgroud)
然后该函数将返回一个数值,例如:[1-9][0-9]{9}
最后一个数字是校验和.
我担心的是:
注1:我不想使用uuid,因为它要与客户沟通,10个数字比36个字符uuid更容易沟通.
注意2:该函数很少被调用,SELECT get_new_rand_id()
但会在id-column上被指定为默认值而不是nextval()
.
编辑:好的,下面的讨论很好!以下是对原因的一些解释:
那么为什么我会用这种方式过度复杂呢?purpouse是隐藏客户的主键.
我给每个新客户一个唯一的customerId(在db中生成序列号).由于我与客户沟通该号码,我的竞争对手监控我的业务是一项相当简单的任务(还有其他数字,例如发票nr和订单nr具有相同的属性).正是这种监控我想更加努力(注意:并非不可能,但更难).
为什么是校验位?
在有任何关于隐藏序列号的讨论之前我添加了一个checkdigit到ordernr,因为在制作中的某些点有klumbsy手指,我的想法是这将是一个很好的做法,以保持在未来.
在阅读完讨论后,我当然可以看到我的方法不是解决问题的最佳方法,但我对如何解决它没有其他好处,所以请在这里帮助我.
int*_*tgr 18
为了从串行生成唯一且随机的标识符,使用密码可能是个好主意.由于它们的输出是双射的(输入和输出值之间存在一对一的映射) - 与哈希不同,您不会发生任何冲突.这意味着您的标识符不必像哈希一样长.
大多数加密密码在64位或更大的块上工作,但PostgreSQL wiki有一个示例PL/pgSQL过程,用于"非加密"密码函数,该函数适用于(32位)int
类型.免责声明:我自己没有尝试过使用此功能.
要将它用作主键,请从Wiki页面运行CREATE FUNCTION调用,然后在空表上执行:
ALTER TABLE foo ALTER COLUMN foo_id SET DEFAULT pseudo_encrypt(nextval('foo_foo_id_seq')::int);
Run Code Online (Sandbox Code Playgroud)
瞧!
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)
Run Code Online (Sandbox Code Playgroud)