0

我有一个表输入和一个派生表参数

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该触发器将在插入时插入Inputs。如果您曾经删除或更新此列,Parameters那么维护Inputs会很复杂。当 in 中没有对应的行时,您必须删除行Parameters- 您需要维护 counts in Inputs,以知道何时 in 中没有对应的行Parameters。并发插入/更新/删除性能会很糟糕,因为任何更改Parameters都必须阻止Inputs. 这一切都是丑陋和糟糕的——视图是更好的解决方案。

于 2010-08-06T14:44:24.357 回答