我有一个表Inputs和一个派生表参数
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 );
}
我应该如何最好地解决MyParameter子查询的重复问题?
有关清理此类查询的其他任何提示
答案 0 :(得分:3)
您应该避免使用非规范化表格。您应该使用视图来轻松查看参数表。这会更容易。
如果您的视图速度不够快,您应该只使用反规范化的摘要表。但是,任何非规范化的表都应该使用触发器来维护,否则你会冒这个表不同步的风险。
为此,您可以在Parameters
上创建一个触发器,该触发器会在插入时upsert进入Inputs
。如果您在Parameters
上删除或更新此列,则维护Inputs
会很复杂。如果Parameters
中没有相应的行,则必须删除行 - 您需要在Inputs
中维护计数,以了解Parameters
中何时没有相应的行。并发插入/更新/删除性能会很糟糕,因为Parameters
中的任何更改都必须阻止Inputs
中的行。这一切都是丑陋和糟糕的 - 视图是更好的解决方案。