我正在努力做很多个小时。我需要创建100.000行,时间戳是主键。这就是为什么它必须是唯一的。
我写了一些代码,它可以生成100个随机时间戳,但如果我尝试超过100个,如1000或10000,我有一个错误,就像那样
错误:重复键值违反了唯一约束“position_pkey” SQL状态:23505详细信息:密钥(“timestamp”)=(2014-03-09 04:03:16.843499)已经存在。
我不知道如何创建100.000时间戳唯一。
这是我的功能
CREATE OR REPLACE FUNCTION generate_random(count integer DEFAULT 1)
RETURNS SETOF timestamp AS
$BODY$
BEGIN
RETURN QUERY SELECT distinct NOW()::timestamp + '10ms'::interval *RANDOM()*RANDOM()
FROM generate_series(0,count);
--SELECT (NOW() - '10000000'::INTERVAL * ROUND(RANDOM() * RANDOM()))::timestamp
-- FROM GENERATE_SERIES(1, count);
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 1000;
这是generate_random函数,可以随机生成双数。
CREATE OR REPLACE FUNCTION generate_random(c integer DEFAULT 1, min double precision DEFAULT 0.0, max double precision DEFAULT 1.0)
RETURNS SETOF double precision AS
$BODY$
BEGIN
RETURN QUERY SELECT min + (max - min) * RANDOM()
FROM GENERATE_SERIES(1, c);
END;
$BODY$
LANGUAGE plpgsql VOLATILE STRICT
COST 100
ROWS 1000;
我在查询中将此函数称为
INSERT INTO "mytable"(
"timestamp", x, y, z)
VALUES (generate_random(1000), generate_random(1000, 0, 50), generate_random(1000, 0, 50), generate_random(1000, 0, 50));
所以,我想创建100.000行,这些行是唯一的时间戳和一些随机的双数字(无论是否独特)
答案 0 :(得分:1)
保证唯一时间戳的唯一方法是在插入之间添加延迟。相反,您可以使用序列
create table mytable (
s serial primary key,
ts timestamp,
x int,
y int,
z int
);
insert into mytable (ts, x, y, z)
select
clock_timestamp(),
500 * RANDOM(),
500 * RANDOM(),
500 * RANDOM()
from generate_series(1, 1000)
;
答案 1 :(得分:1)
使用feistel cypher从序列进行1:1映射的相同方法可用于时间戳。
或者您可以使用非重复的迭代伪随机数生成器。
主要的是,如果将结果缩小到较小的空间,则必须小心,因为会出现碰撞。
答案 2 :(得分:0)
permuteseq扩展名可以是 用于生成包含具有随机外观的唯一值的区间 分布。
这是一个在其中生成100000
个唯一时间戳的示例
10000000
(1000万)个可能的值,基于
将伪随机序列中的元素乘以10ms
个区间
已添加到now()
。
CREATE EXTENSION permuteseq;
CREATE TABLE uniq_tstamp(t timestamp);
INSERT INTO uniq_tstamp
SELECT now()+range_encrypt_element(elt, 1, 10000000, 1234::bigint) * '10ms'::interval AS t
FROM generate_series(1,100000) AS elt;
1234
常量是一个混淆密钥:选择您想要获得不同系列结果的任何其他bigint
。
如果我们根据值的单一性和区间大小检查结果:
SELECT min(t),max(t),count(distinct t) FROM uniq_tstamp ;
min | max | count
----------------------------+----------------------------+--------
2017-02-02 16:00:50.750651 | 2017-02-03 19:47:30.350651 | 100000
(1 row)
查看第一个值:
SELECT * FROM uniq_tstamp limit 10;
t
----------------------------
2017-02-03 14:42:44.420651
2017-02-03 11:40:37.200651
2017-02-02 17:28:50.470651
2017-02-03 00:34:12.060651
2017-02-03 00:02:16.780651
2017-02-03 05:53:41.550651
2017-02-02 21:53:49.900651
2017-02-03 02:58:37.420651
2017-02-03 05:25:00.730651
2017-02-03 09:13:42.110651
permuteseq
应用的随机化不是加密级别的,但它是合理的。