PostgreSQL - 带有 id 的种子 table
PostgreSQL - seed table with ids
有没有一种优雅的方法可以用这种方式用虚拟数据填充 table。
我需要创建这个 table:
CREATE TEMP TABLE counter(
id int,
userID int,
dateCreated date
);
种子序列应该是:
- Id - 从 1 到 100000000
- UserId - 1 到 1000000,每个 1M Id userid 应该从 1 重新开始。
所以f.eid 1000000 userid 1000000,那么当id超过1M时userid应该从1重新开始。
f.eid=1000001,userid=1
- 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; $$
有没有一种优雅的方法可以用这种方式用虚拟数据填充 table。
我需要创建这个 table:
CREATE TEMP TABLE counter(
id int,
userID int,
dateCreated date
);
种子序列应该是:
- Id - 从 1 到 100000000
- UserId - 1 到 1000000,每个 1M Id userid 应该从 1 重新开始。 所以f.eid 1000000 userid 1000000,那么当id超过1M时userid应该从1重新开始。 f.eid=1000001,userid=1
- 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; $$