0

テーブル Inputs と派生テーブル Parameters があります

CREATE TABLE Configurables
(
  id SERIAL PRIMARY KEY
);

CREATE TABLE Inputs
(
  configurable integer REFERENCES Configurables( id ),
  name text,
  time timestamp,
  PRIMARY KEY( configurable, name, time )
);

CREATE TABLE Parameters
(
  configurable integer,
  name text,
  time timestamp,
  value text,
  FOREIGN KEY( configurable, name, time ) REFERENCES Inputs( configurable, name, time )
);

次のクエリは、パラメーターが変更されているかどうか、またはまだ存在しないかどうかを確認し、パラメーターに新しい値を挿入します。

QString PostgreSQLQueryEngine::saveParameter( int configurable, const QString& name, const QString& value )
{
  return QString( "\
    INSERT INTO Inputs( configurable, name, time ) \
      WITH MyParameter AS \
      ( \
        SELECT configurable, name, time, value \
        FROM \
        ( \
          SELECT configurable, name, time, value \
          FROM Parameters \
          WHERE (configurable = %1) AND (name = '%2') AND time =  \
          ( \
            SELECT max( time ) \
            FROM Parameters \
            WHERE (configurable = %1) AND (name = '%2') \
          ) \
          UNION \
          SELECT %1 AS configurable, '%2' AS name, '-infinity' AS time, NULL AS value \
        )AS foo \
      ) \
      SELECT %1 AS configurable, '%2' AS name, 'now' AS time FROM MyParameter \
      WHERE time = (SELECT max(time) FROM MyParameter) AND (value <> '%3' OR value IS NULL); \
      \
    INSERT INTO Parameters( configurable, name, time, value ) \
      WITH MyParameter AS \
      ( \
        SELECT configurable, name, time, value \
        FROM \
        ( \
          SELECT configurable, name, time, value \
          FROM Parameters \
          WHERE (configurable = %1) AND (name = '%2') AND time =  \
          ( \
            SELECT max( time ) \
            FROM Parameters \
            WHERE (configurable = %1) AND (name = '%2') \
          ) \
          UNION \
          SELECT %1 AS configurable, '%2' AS name, '-infinity' AS time, NULL AS value \
        )AS foo \
      ) \
      SELECT %1 AS configurable, '%2' AS name, 'now' AS time, '%3' AS value  FROM MyParameter \
      WHERE time = (SELECT max(time) FROM MyParameter) AND (value <> '%3' OR value IS NULL); \
    " ).arg( configurable ).arg( name ).arg( value );
}

2 つの MyParameter サブクエリの重複を解決するにはどうすればよいですか?

このようなクエリのクリーンアップに関するその他のヒント

4

1 に答える 1

3

非正規化されたテーブルは避ける必要があります。パラメータ テーブルの概要を簡単に確認するには、ビューを使用する必要があります。それははるかに簡単です。

ビューの速度が十分でない場合にのみ、非正規化されたサマリー テーブルを使用する必要があります。ただし、正規化されていないテーブルは、トリガーを使用して維持する必要があります。そうしないと、このテーブルが同期しなくなるリスクがあります。

このために、挿入時にアップサートするトリガーParametersを作成できます。この列を削除または更新すると、維持が複雑になります。に対応する行がない場合は、行を削除する必要があります。に対応する行がない場合は、 でカウントを維持する必要があります。の変更はの行をブロックする必要があるため、同時挿入/更新/削除のパフォーマンスは最悪です。これはすべて醜く悪いことです - ビューははるかに優れた解決策です。InputsParametersInputsParametersInputsParametersParametersInputs

于 2010-08-06T14:44:24.357 に答える