PostgreSQL - 带有 id 的种子 table

PostgreSQL - seed table with ids

有没有一种优雅的方法可以用这种方式用虚拟数据填充 table。

我需要创建这个 table:

CREATE TEMP TABLE counter(
    id int,
    userID int,
    dateCreated date
);

种子序列应该是:

  1. Id - 从 1 到 100000000
  2. UserId - 1 到 1000000,每个 1M Id userid 应该从 1 重新开始。 所以f.eid 1000000 userid 1000000,那么当id超过1M时userid应该从1重新开始。 f.eid=1000001,userid=1
  3. dateCreated 也应该每增加 1M id,所以当计数器超过 1M 时,将添加下一个日期。 F.e id = 1000000 dateCreated 1900.01.01, id = 1000001 dateCreated = 1900.01.02.

我试过 generate_series,这对 id 没问题。 也有 while 循环,但它花费的时间太长了。

您可以使用两个 generate_series() 调用和一些数学运算来填充 id 列:

insert into counter(id, userid, datecreated)
select (t.userid - 1) * 100 + x.counter, 
        t.userid, 
        date '1900-01-01' + (t.userid - 1)
from generate_series(1,1000000) as t(userid)
  cross join generate_series(1,100) x(counter)

使用模运算符和整数除法:

INSERT INTO counter(id, userid, datecreated)
SELECT
  num AS id,
  (num - 1) % 1000000 + 1 AS userid,
  date '1900-01-01' + (interval '1 day' * (num - 1) / 1000000) AS datecreated
FROM generate_series(1, 100000000) AS numbers(num);

演示:https://dbfiddle.uk/?rdbms=postgres_13&fiddle=4a285f2942c0dd66255f32df0eeee943

个人感觉一次性创建100M行很多,所以我会分成100批1M。

我还会使用 SERIAL 列来自动处理 id 列。

示例 Fiddle:https://dbfiddle.uk/?rdbms=postgres_13&fiddle=86fa35f68530860ac90ea70d5b9f7101

(fiddle被限制在space所以用了假数字,下面是做100批1M的版本...)

do $$
begin

CREATE TEMP TABLE counter(
    id SERIAL PRIMARY KEY,
    userID int,
    dateCreated date
);

for batch in 0..99 loop

  INSERT INTO
    counter (
      userID,
      dateCreated
    )
  SELECT
    1000000 * batch + user_id,
    '1900-01-01'::date + batch * INTERVAL '1 day' 
  FROM
    generate_series(1, 1000000) user_id
  ;

end loop;

end; $$