Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL重用更新计算_Postgresql_Sql Update_Query Optimization - Fatal编程技术网

PostgreSQL重用更新计算

PostgreSQL重用更新计算,postgresql,sql-update,query-optimization,Postgresql,Sql Update,Query Optimization,我有一个用于跟踪用户在游戏中的进度的表格,看起来像: create table progressions ( user_id int, attempt_count int, correct_count int, accuracy float, state text ); update progressions p set attempt_count = p.attempt_count + {attempt_count}, c

我有一个用于跟踪用户在游戏中的进度的表格,看起来像:

create table progressions (
  user_id       int,
  attempt_count int,
  correct_count int,
  accuracy      float,
  state         text
);
update
  progressions p
set
  attempt_count = p.attempt_count + {attempt_count},
  correct_count = p.correct_count + {correct_count},
  accuracy      = p.accuracy * (1 - {alpha}) + ({correct_count} / {attempt_count}::float) * {alpha}
where
  user_id       = {user_id};
我想创建一个查询,通过以下方式更新用户的进度:

  • 添加一定数量的尝试
  • 添加一定数量的更正
  • 重新计算精度(作为衰减平均值)
  • 重新计算状态(基于新的精度)
现在,前3点可以通过以下方式轻松实现:

create table progressions (
  user_id       int,
  attempt_count int,
  correct_count int,
  accuracy      float,
  state         text
);
update
  progressions p
set
  attempt_count = p.attempt_count + {attempt_count},
  correct_count = p.correct_count + {correct_count},
  accuracy      = p.accuracy * (1 - {alpha}) + ({correct_count} / {attempt_count}::float) * {alpha}
where
  user_id       = {user_id};
当我想基于精度更新状态时,问题就出现了,我需要在条件中重用精度表达式的结果:

我想我可以在这种情况下使用CTE(可能涉及原子性),但我想知道是否有其他方法可以让我重用精度表达式的结果而不重新计算它


如果没有,如果我重复了
N
次,PostgreSQL是否会在内部对其进行优化?

您是否考虑过使用更新前触发器维护这些计算字段

create function progressions_accuracy_upd() returns trigger as $$
begin
  new.state := case
    when new.accuracy > 0.9 then 'exceptional'
    when new.accuracy > 0.8 then 'pretty good'
    …
  return new;
end;
$$ language plpgsql;

create trigger progressions_accuracy_upd before update on progressions
for each row when (new.accuracy is distinct from old.accuracy)
execute procedure progressions_accuracy_upd();

就这一点而言,您是否考虑过直接在应用程序中计算state字段?(准确度字段更有意义,以便查询准确度在x和y之间的玩家,但状态似乎不需要存储尽可能多的行。)

您是否考虑过使用更新前触发器来维护这些计算字段

create function progressions_accuracy_upd() returns trigger as $$
begin
  new.state := case
    when new.accuracy > 0.9 then 'exceptional'
    when new.accuracy > 0.8 then 'pretty good'
    …
  return new;
end;
$$ language plpgsql;

create trigger progressions_accuracy_upd before update on progressions
for each row when (new.accuracy is distinct from old.accuracy)
execute procedure progressions_accuracy_upd();
就这一点而言,您是否考虑过直接在应用程序中计算state字段?(准确度字段更有意义,以便查询准确度在x和y之间的玩家,但state似乎不必要存储行数和字符串数。)