向:
目前我已将所有数据整理到一个PostgreSQL“Bigtable”表中(大约有1.2M行)。现在我需要将设计拆分为单独的表,这些表都依赖于Bigtable。有些表可能有子表。该模型看起来非常像雪花。
问题:
将数据插入表格的最佳选择是什么?我想用'SQL'或PLgSQL编写的函数进行插入。但问题仍然是使用自动生成的ID-s。
此外,如果你知道哪些工具可以让这个问题解决更容易,那么发帖!
// 编辑我添加了示例,这不仅仅是为了说明的真实案例
答案 0 :(得分:1)
1.2 M行不是太多。最好的工具是从控制台“psql”执行的sql脚本。如果您有一些较新版本的Pg,那么您可以在必要时使用内联函数(DO语句)。但可能最有用的命令是INSERT INTO SELECT语句。
-- file conversion.sql
DROP TABLE IF EXISTS f1 CASCADE;
CREATE TABLE f1(a int, b int);
INSERT INTO f1
SELECT x1, y1
FROM data
WHERE x1 = 10;
...
-- end file
psql mydb -f conversion.sql
答案 1 :(得分:0)
如果我理解你的问题,你可以使用这样的psql函数:
CREATE OR REPLACE FUNCTION migration() RETURNS integer AS
$BODY$
DECLARE
currentProductId INTEGER;
currentUserId INTEGER;
currentReg RECORD;
BEGIN
FOR currentReg IN
SELECT * FROM bigtable
LOOP
-- Product
SELECT productid INTO currentProductId
FROM product
WHERE name = currentReg.product_name;
IF currentProductId IS NULL THEN
EXECUTE 'INSERT INTO product (name) VALUES (''' || currentReg.product_name || ''') RETURNING productid'
INTO currentProductId;
END IF;
-- User
SELECT userid INTO currentUserId
FROM user
WHERE first_name = currentReg.first_name and last_name = currentReg.last_name;
IF currentUserId IS NULL THEN
EXECUTE 'INSERT INTO user (first_name, last_name) VALUES (''' || currentReg.first_name || ''', ''' || currentReg.last_name || ''') RETURNING userid'
INTO currentUserId;
-- Insert into userAdded too with: currentUserId and currentProductId
[...]
END IF;
-- Rest of tables
[...]
END LOOP;
RETURN 1;
END;
$BODY$
LANGUAGE plpgsql;
select * from migration();
在这种情况下,假设每个表都运行自己的主键序列,并且我减少了表中字段的数量以简化。 我希望你能提供帮助。
答案 2 :(得分:0)
不需要使用函数(除非我误解了你的问题)
如果您的id列都定义为serial
列(即它们自动生成值),则可以使用简单的INSERT语句完成此操作。这假设目标表都是空的。
INSERT INTO users (firstname, lastname)
SELECT DISTINCT firstname, lastname
FROM bigtable;
INSERT INTO category (name)
SELECT DISTINCT category_name
FROM bigtable;
-- the following assumes a column categoryid in the product table
-- which is not visible from your screenshot
INSERT INTO product (product_name, description, categoryid)
SELECT DISTINCT b.product_name, b.description, c.categoryid
FROM bigtable b
JOIN category c ON c.category_name = b.category_name;
INSERT INTO product_added (product_productid, user_userid)
SELECT p.productid, u.userid
FROM bigtable b
JOIN product p ON p.product_name = b.product_name
JOIN users u ON u.firstname = b.firstname AND u.lastname = b.lastname