次PostgreSQLのクエリでコードの重複を解決する方法は?
-
26-09-2019 - |
質問
私はテーブル入力と派生テーブルのパラメータ
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サブクエリ?
このようなクエリをクリーンアップ上の任意の他のヒント
解決
あなたは、デ正規化された表を避ける必要があります。あなたは、パラメータテーブルの簡単な概要については、ビューを使用する必要があります。それははるかに、はるかに簡単になります。
あなたのビューが十分に速くない場合は、あなただけのデ正規化されたサマリー表を使用する必要があります。しかし、いずれのデ正規化されたテーブルは、このテーブルが同期して行くことのようにそうでなければ、リスク、トリガーを使用して維持されなければならない。
はこのためにあなたがParameters
にトリガーを作成することができます<のhref =「http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE」のrel挿入のInputs
に= "nofollowをnoreferrer">アップサートを。あなたはParameters
に、この列を削除または更新した場合、その後維持Inputs
が複雑になります。あなたはParameters
には、対応する行がありません時に行を削除する必要があるだろう - あなたはInputs
には、対応する行がありません時に知って、Parameters
でカウントを維持する必要があると思います。 Parameters
に変更がInputs
の行をブロックしなければならないように同時挿入/更新/削除性能は、吸引されます。これは、すべての醜いと悪いです - ビューは、はるかに優れたソリューションです。