【问题标题】:Random default column value that rerolls on conflict冲突时重新滚动的随机默认列值
【发布时间】:2020-04-12 00:55:55
【问题描述】:

我有一列我想default 到指定范围内随机生成的int8。我还希望此列是唯一的,因此如果生成的随机值已经存在,则应重新滚动。

所以我的问题是,在 PostgreSQL 中执行上述操作最惯用的方法是什么,最好具有良好的性能并支持批量插入。

例如,如果我有一个包含 nameid 列的 Person 表,并且我希望 idint8 范围内的随机唯一 (0, 999999)。我希望能够插入 PaulKellyDavidKatie 并得到如下内容:

| Name  |   id   |
+-------+--------+
| Paul  | 314563 |
| Kelly | 592103 |
| David | 127318 |
| Katie | 893134 |

没有重复的风险,也没有插入失败的风险。

范围不会大到足以让我安全地假设它们永远不会发生碰撞(即生日悖论)。

我还应该说我确实想要真正的不可预测的随机性,所以序列上的密码不会计算在内。

关于如何生成随机数有多种答案,所以问题的主要焦点是唯一性方面。

话虽如此,在任意大范围内均匀生成int8 的干净且有效的方法将不胜感激。当n > 2 ^ 53(可能更早)时,random() * n 开始出现间隙。

【问题讨论】:

  • 请显示示例数据。一个唯一的随机生成的数字是什么意思
  • 编辑了问题。我的意思是int8 在我能够指定的范围内大致均匀生成。
  • 这就是所谓的数据编码
  • @HimanshuAhuja 你是什么意思?
  • @LukStorms 密钥将用于 URL 和客户端代码内部,因此我不想透露创建顺序或行创建率/计数等信息。

标签: sql postgresql random


【解决方案1】:

一个可能的解决方案:

create table t (name varchar (50), id int);

-- 1. generate a list of possible ids
-- 2. cast the id in varchar to make a string after that
-- 3. aggregate all the possible ids in a string with a ',' separator
-- 4. make the string a list
-- 5. select a random value in this list
-- 6. insert the new id for the wanted name. Here 'test'
with cte as 
(
  SELECT a.n as possible_id
  from generate_series(1, 150000) as a(n)
  where not exists (select 1 from t where t.id = a.n)
)
, cte_s as 
(
  select 
    (
        string_to_array( 
            string_agg( 
                cast(possible_id as varchar)
                , ','
            )
            , ','
        )
    )[floor(random() * 150000 + 1)] as new_id
  from cte
)
insert into t
values ('test', (select new_id from cte_s)::int); 

-- test that your code doing what you want
select *
from t;

http://sqlfiddle.com/#!17/17d42/26

当然,您可以根据需要修改最大金额。

【讨论】:

  • 您介意浏览一下代码吗?我不太确定所有字符串的用途,似乎除了'test' 名称之外,我还想坚持使用int8
  • 我按要求编辑了答案。你有 sqlfiddle 链接来测试它,但如果你有任何其他问题,请不要犹豫。
猜你喜欢
  • 1970-01-01
  • 2014-09-17
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-17
  • 1970-01-01
  • 2018-06-30
相关资源
最近更新 更多