将数据插入到不同的引用表中

时间:2016-05-09 16:10:10

标签: sql postgresql

如果我的问题制定不当,我很抱歉,我将在下面详细解释。

我在hapi.js中编写API,因此编程语言是javascript。 Postgres版本:9.4.7

我的数据库有3个表:

  1. 评分
  2. ratings_tags
  3. 标记
  4. 表“ratings_tags”包含哪些评级标记有哪些标记。

    我有一个端点/data/{id}的api,我已经可以获得一个评级。有效但可能不是最好的查询如下:

    SELECT 
        r.id, 
        r.score, 
        r.comment, 
        r.datetime, 
        r.type, 
        r.customer_id, 
        array_remove(array_agg(t.tag), NULL) as tags 
    FROM 
        ratings r 
    LEFT OUTER JOIN 
        ratings_tags rt 
    ON 
        r.id = rt.rating_id 
    LEFT OUTER JOIN 
        tags t 
    ON 
        rt.tag_id=t.id 
    WHERE
        r.id = $1
    GROUP BY 
        r.id
    

    我已经编写了前端,因此我可以编辑数据点,现在我想再次保存它。我现在主要关心标签,但它应该保存整个事情。 我认为它应该做什么:

    1. 将所有评分信息重新插入表ratings
    2. 将当前不存在的所有标记插入表tags
    3. 将评级和标签之间的关系插入表ratings_tags,除非它们已存在。
    4. 以某种方式删除不再存在的关系。
    5. 我认为在保存新评级之前删除所保存评级与其标签之间的所有关系可能会有好处吗?

      我尝试了很多,但是由于对标签关系的评级,我想知道如果我想将数据点保存到/data/{id},api应该执行的正确查询。

      更新

      以下是似乎有效的前两个步骤:

      # STEP 1 (values are placeholders)
      INSERT INTO ratings(rating_id, score, comment, datetime, type, customer_id)
          VALUES(r.id, r.score, r.comment, r.datetime, r.type, r.customer_id);
      
      # STEP 2
      CREATE OR REPLACE FUNCTION insertTagsFromArray(varchar[]) RETURNS void AS $$
      DECLARE
          new_tag varchar;
      BEGIN
          FOREACH new_tag IN ARRAY $1
          LOOP
              INSERT INTO tags(tag)
                  SELECT (new_tag)
                  WHERE NOT EXISTS (SELECT tag FROM tags WHERE tag = new_tag);
          END LOOP;
      END;
      $$ LANGUAGE plpgsql;
      

1 个答案:

答案 0 :(得分:1)

你现在的问题有点过于宽泛,但我会有一个问题

1. 将所有评分信息重新插入表评分

那只是一个由编程语言调用的简单插入语句。您需要检索生成的插入ID。你的(未提及的)编程语言应该为你解决这个问题。

2. 将所有当前不存在的标记插入表格标记

如上所述。恭喜能够为此任务编写存储函数。你并不像你想象的那样有点新鲜。

与此同时,使用一个人完成这项任务可能有点过头了。使用编程语言完成循环的简单插入可能更容易使用。

这引出了一个问题,你选择了正确的编程语言吗?听起来不像!

3. 将评级和代码之间的关系插入表ratings_tags,除非它们已经存在。

更高效的是做所谓的UPSERT。插入记录,如果已存在则更新它。在您的情况下,如果您不关心更新它,您可以简单地忽略。这比查询数据库以找出其中的内容然后插入缺少的内容更有效。

再次,您的编程语言将能够在这里为您提供帮助。

4. 以某种方式删除不再存在的关系。

没必要。您需要在关系中添加ON DELETE CASCADE,数据库将自动为您处理。

5. 我认为在保存新评级之前删除所保存评级与其标签之间的所有关系可能会有好处吗?

不,那效率最低。