1

进入

目前我已经将所有数据抓取到一个 PostgreSQL 'Bigtable' 表中(大约有 120 万行)。现在我需要将设计拆分为单独的表,这些表都依赖于 Bigtable。一些表可能有子表。该模型看起来很像雪花。

问题

将数据插入表的最佳选择是什么?我想用“SQL”或 PLgSQL 编写的函数进行插入。但问题仍然在于自动生成的 ID。

另外,如果您知道哪些工具可以使解决此问题更容易,请发布!

//编辑我添加了例子,这不是真实的例子,只是为了说明.

4

3 回答 3

1

120 万行不算太多。最好的工具是从控制台“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
于 2011-12-29T13:15:31.867 回答
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();

在这种情况下,假设每个表都运行自己的主键序列,并且我减少了表中的字段数以简化。我希望你对你有所帮助。

于 2011-12-30T12:16:47.503 回答
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
于 2011-12-30T12:46:49.070 回答