冗余与聚合数据的性能

Redundancy vs. aggregated Data for performance

我有几个 code/value/synonyms 列表(i.a。ICD 代码),其中包括多个有效期,汇总成多个版本(每年一个)。

所以现在我可以选择完全规范化的方法,具有以下结构:

VERSIONS(id INT PRIMARY KEY, name VARCHAR)
CODES(id INT PRIMARY KEY, code VARCHAR)
VALUES(id INT PRIMARY KEY, text VARCHAR)

CODEVALUES(code_id INT FOREIGN KEY CODES.id, 
    value_id INT FOREIGN KEY VALUES.id, 
    version_id INT FOREIGN KEY VERSIONS.id,
    synonym_nr INT) 
    with PK(code_id, value_id, version_id)

这样我最多可以有 14 条代码值记录,在过去 14 年中没有改变。对于具有最多 20 个同义词的 >14000 个代码,我最终在 CODEVALUES 中得到了 >2,000,000 条记录。

另一种方法是使用聚合 table,例如

CODES(code VARCHAR, value VARCHAR, synonym_nr INT, min_version INT, max_version INT)

没有 FK。对于 code/value/synonym_nr 的每个组合,只有一个记录。

我知道规范化,但我正在努力降低开发和管理的复杂性,因为我需要一个 OR/M 实体用于每个 SQL table,包括它的关系和因为我有几十个这样的代码列表,class 数字的因子 4 很重要,

我想知道这些备选方案之间是否存在性能差异。

更新:

这些列表上的查询是这样的,我查找具有特定版本的特定代码并想要该代码的默认值 (synonym_nr = 0)。 由于这些查询通常是较大查询的一部分,因此每个查询事务可能有数 10k 到 100k 的此类代码查找。 使用方法#1,我至少有 2 个连接,并且 Db 必须为每个版本保存一个映射记录(code/value 的冗余)。虽然方法 #2 定义了一个有效的版本范围,但必须通过

查询
WHERE version >= min_version AND version <= max_version

所以它是连接和更多记录(索引效率?)与查询约束中的范围比较。会有显着的性能差异吗?

我完全支持@SeanLange;

It will save very little time up front and cost LOTS more in the long run.

现在正确建模,您以后就不必解决其他人的问题了。

考虑为您的版本、代码和值 PK 使用较小的数据类型,即 TINYINT 或 SMALLINT 而不是 INT(如果合适)。考虑聚合 table 的视图,并根据需要将 ORM 指向该视图。

或者,考虑一种不同的建模方法。如果变化率很低,那么对版本号使用 'from' 和 'to' 方法可能会更紧凑。

根据您提出问题的方式,我猜您至少可以合理地胜任 SQL Server。尝试这两种方法并查看 'typical' 查询的查询计划,了解 SQL 服务器如何处理不同的方法。