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描画プログラムの場合です)。ご覧のとおり、ほとんどの値は連続したリビジョン間で同じであるため、テーブルの有用なデータは非常にまばらです。データを保存する方法を探しています

  • レプリケーションを回避し、スペースを効率的に使用します (現在、非スパース表現では、保存したいデータの 10% 未満に 260 GB (データ + インデックス) が必要です)
  • 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

3番目のポイントであなたが何を望んでいるかを正しく理解していると仮定すると、これにより、特定のファイルが特定の値を持つすべてのリビジョンを取得できます。

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 に答える