【问题标题】:Postgresql trigger to calculate total scorePostgresql 触发器计算总分
【发布时间】:2015-07-22 15:10:33
【问题描述】:

我正在尝试学习如何在 postgresql 中创建触发器。我有一张桌子

Thread_user - 表名 线程 ID 用户身份 积分

线程 - 表名 线程 ID 总分

我想更新任何 thread_user 行以更新线程表中的总点数。我需要基本上从 thread_user 中选择 * 其中 thread_id = thread_id 的插入项,然后添加点然后更新线程表中的 thread_points。我相信这是在触发器中完成的,但也许存储过程会更好。

【问题讨论】:

  • 可以从表中的数据计算的值通常不应存储在数据库中。您可能会保存错误的数据。
  • Zahrec,我明白这一点,但这些数字的实际价值与每次计算出来的潜在运行时间相比是值得的。
  • 好的,这是一个正当的理由。只是想确定你知道这一点。我已经为您的问题提供了解决方案。

标签: sql postgresql stored-procedures triggers


【解决方案1】:

第一步是创建一个函数来计算点的总和并更新计算点表中的一行。

之后,您将创建一个触发器,在 user_points 表中插入一行时调用该触发器。

DROP TABLE IF EXISTS user_points CASCADE;
CREATE TABLE user_points (
    id          SERIAL PRIMARY KEY,
    user_id     INT NOT NULL,
    points      INT NOT NULL
);

DROP TABLE IF EXISTS calculated_points CASCADE;
CREATE TABLE calculated_points (
    id          SERIAL PRIMARY KEY,
    user_id     INT  NOT NULL UNIQUE,
    points      INT NOT NULL

);

INSERT INTO calculated_points (user_id, points)
    VALUES
        (1, 0),
        (2, 0);

CREATE OR REPLACE FUNCTION calculate_total_points() 
RETURNS trigger AS $calculate_total_points$
BEGIN
    UPDATE calculated_points 
        SET points = (SELECT SUM(points)
                         FROM user_points
                         WHERE user_id = NEW.user_id)
         WHERE user_id = NEW.user_id;

    RETURN NEW;
END;
$calculate_total_points$ LANGUAGE plpgsql;

CREATE TRIGGER points_added
  AFTER INSERT
  ON user_points
  FOR EACH ROW
  EXECUTE PROCEDURE calculate_total_points();

【讨论】:

  • 注意:随着时间的推移,这会变得越来越慢,因为每次插入一行时都必须读取来自user_points所有行(在calculate_total_points 内)。因此,如果 user_points 包含例如1 亿行,然后向表中插入一行将导致读取 1 亿行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 2011-07-03
  • 2016-11-14
  • 2011-03-15
相关资源
最近更新 更多