5

我有一个表,表示跨项目修订的源文件指标的值,如下所示:

Revision FileA FileB FileC FileD FileE ...
1           45     3    12   123   124
2           45     3    12   123   124
3           45     3    12   123   124
4           48     3    12   123   124
5           48     3    12   123   124
6           48     3    12   123   124
7           48    15    12   123   124

(上述数据的关系视图不同。每行包含以下列:Revision、FileId、Value。计算数据的文件及其修订版存储在 Subversion 存储库中,因此我们试图表示存储库的关系模式中的结构。)

在 10000 个修订版中最多可以有 23750 个文件(ImageMagick绘图程序就是这种情况)。如您所见,连续修订之间的大多数值是相同的,因此该表的有用数据非常稀疏。我正在寻找一种存储数据的方法

  • 避免复制并有效地使用空间(目前非稀疏表示需要 260 GB(数据+索引)来存储不到 10% 的数据)
  • 允许我使用 SQL 查询有效地检索特定修订的值(无需显式循环通过修订或文件)
  • 允许我有效地检索特定指标值的修订。

理想情况下,该解决方案不应该依赖于特定的RDBMS,并且应该与Hibernate兼容。如果这不可能,我可以使用 Hibernate、MySQL 或 PostgreSQL 特定的功能。

4

1 回答 1

5

这就是我可以建模的方式。我省略了 Revisions 表和 Files 表,因为它们应该是不言自明的。

CREATE TABLE Revision_Files
(
    start_revision_number   INT NOT NULL,
    end_revision_number     INT NOT NULL,
    file_number             INT NOT NULL,
    value                   INT NOT NULL,
    CONSTRAINT PK_Revision_Files PRIMARY KEY CLUSTERED (start_revision_number, file_number),
    CONSTRAINT CHK_Revision_Files_start_before_end CHECK (start_revision_number <= end_revision_number)
)
GO

要获取特定版本的文件的所有值,您可以使用以下查询。使用外部连接连接到文件表将让您获得那些没有为该修订定义值的文件。

SELECT
    REV.revision_number,
    RF.file_number,
    RF.value
FROM
    Revisions REV
INNER JOIN Revision_Files RF ON
    RF.start_revision_number <= REV.revision_number AND
    RF.end_revision_number >= REV.revision_number
GO

假设我正确理解了您在第三点中想要的内容,这将使您获得特定文件具有特定价值的所有修订:

SELECT
    REV.revision_number
FROM
    Revision_Files RF
INNER JOIN Revisions REV ON
    REV.revision_number BETWEEN RF.start_revision_number AND RF.end_revision_number
WHERE
    RF.file_number = @file_number AND
    RF.value = @value
GO
于 2009-01-05T15:51:30.643 回答