【发布时间】:2014-04-07 09:29:52
【问题描述】:
在PostgreSQL中,如何为列生成随机唯一整数, 返回哪个不存在于表格列中?
【问题讨论】:
标签: postgresql
在PostgreSQL中,如何为列生成随机唯一整数, 返回哪个不存在于表格列中?
【问题讨论】:
标签: postgresql
参见pseudo_encrypt 函数,该函数基于Feistel network 技术实现排列。结合 postgres 序列,这保证了结果的唯一性以及人眼的随机性。
例子:
CREATE OR REPLACE FUNCTION pseudo_encrypt(VALUE int) returns int AS $$
DECLARE
l1 int;
l2 int;
r1 int;
r2 int;
i int:=0;
BEGIN
l1:= (VALUE >> 16) & 65535;
r1:= VALUE & 65535;
WHILE i < 3 LOOP
l2 := r1;
r2 := l1 # ((((1366 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
l1 := l2;
r1 := r2;
i := i + 1;
END LOOP;
RETURN ((r1 << 16) + l1);
END;
$$ LANGUAGE plpgsql strict immutable;
create sequence seq maxvalue 2147483647;
create table tablename(
id int default pseudo_encrypt(nextval('seq')::int),
[other columns]
);
可以在以下位置找到具有 64 位输出空间的变体:pseudo_encrypt() function in plpgsql that takes bigint。
编辑:pseudo_encrypt 仅实现一种排列,并且不接受用户提供的密钥。如果您更喜欢自己的排列,具体取决于密钥,您可以考虑skip32(基于 Skipjack 的 32 位分组密码,具有 10 字节宽的密钥)。
plpgsql 函数(从 Perl/C 移植)在以下位置可用: https://wiki.postgresql.org/wiki/Skip32
【讨论】:
create table tablename( id int default pseudo_encrypt(nextval('seq')::int), [other columns] );