【问题标题】:Set results to be array in a new column for over a million rows -postgreSQL将结果设置为新列中超过一百万行的数组-postgreSQL
【发布时间】:2019-12-12 06:54:45
【问题描述】:

我正在尝试将所有照片 url 放入一个数组中,并将该数组设置为另一个表中的新列。这些表具有一对多的关系。我的 list_reviews 表中有大约 100 万行和大约 300 万张照片。

有没有办法分批做到这一点?当我尝试一次性完成所有操作时,我得到了空数组。

https://www.postgresql.org/message-id/20051219121211.002f7e87.gry@ll.mit.eduPostgresql select rows(a result) as array

如果我一次只做一个,那么这些工作。我一直在考虑尝试使用此处找到的 STREAMING,https://github.com/vitaly-t/pg-promise/wiki/Learn-by-Example#into-database,但不确定我是否完全理解这里发生的事情。

CREATE TABLE list_reviews (
  id SERIAL PRIMARY KEY,
  product_id INT,
  photos TEXT[]);

CREATE TABLE review_photos (
  id SERIAL,
  review_id INT REFERENCES list_reviews(id) ON DELETE CASCADE,
  url TEXT);

UPDATE list_reviews SET photos = array(
   SELECT url
   FROM review_photos
   WHERE review_photos.id = list_reviews.id 
   AND list_reviews.id = 5);

list_reviews 看起来像:

+----+------------+--------+--+
| id | product_id | photos |  |
+----+------------+--------+--+
|  5 |          1 | []     |  |
+----+------------+--------+--+

review_photos 看起来像:

+----+-----------+------------+--+
| id | review_id |   photos   |  |
+----+-----------+------------+--+
|  1 |         5 | something1 |  |
|  2 |         5 | something2 |  |
|  3 |         5 | something3 |  |
+----+-----------+------------+--+

并且希望看到 list_reviews:

+----+------------+--------------------------------------+--+
| id | product_id |                photos                |  |
+----+------------+--------------------------------------+--+
|  5 |          1 | [something1, something2, something3] |  |
+----+------------+--------------------------------------+--+

【问题讨论】:

    标签: sql node.js postgresql pg-promise


    【解决方案1】:

    您的代码基本上看起来没问题。我更喜欢使用array_agg()(因为操作更明确),但 Postgres 允许为array 设置结果集。

    一个问题是过滤。我想你打算:

    UPDATE list_reviews lr
        SET photos = array(SELECT rp.url
                           FROM review_photos rp
                           WHERE rp.id = lr.id 
                          )
        WHERE lr.id = 5;
    

    您的查询将使用 id = 5 的照片中的网址更新 list_reviews 中的所有行。

    您可以在处理过程中通过在lr.id 上设置范围来批量执行此操作。例如:

    UPDATE list_reviews lr
        SET photos = array(SELECT rp.url
                           FROM review_photos rp
                           WHERE rp.id = lr.id 
                          )
        WHERE lr.id > 0 and lr.id < 10000;
    

    但是,替换现有表可能更简单:

    create temporary table temp_list_reviews as
        select id, product_id,  -- all columns but photos
               array(SELECT rp.url
                               FROM review_photos rp
                               WHERE rp.id = lr.id 
                              ) as photos
        from list_reviews;
    
    truncate table list_reviews;
    
    insert into list_reviews (id, product_id, photos)
        select id, product_id, photo
        from temp_list_reviews;
    

    出于日志记录的考虑,批量插入通常比更新快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 2018-12-26
      相关资源
      最近更新 更多