희소 데이터 : RDBMS의 효율적인 저장 및 검색
-
03-07-2019 - |
문제
다음과 같은 프로젝트 개정판에서 소스 파일 메트릭의 값을 나타내는 테이블이 있습니다.
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
(위의 데이터의 관계형보기에는 다릅니다. 각 행에는 다음 열이 포함되어 있습니다. 개정, 파일, 값. 파일 및 데이터가 계산되는 개정판은 전복 저장소에 저장되므로 저장소의 저장을 나타내려고 노력하고 있습니다. 관계형 스키마의 구조.)
100000 개정판에는 최대 23750 개의 파일이있을 수 있습니다 (이것은 경우입니다. Imagemagick 드로잉 프로그램). 보시다시피, 대부분의 값은 연속 개정 사이에서 동일하므로 테이블의 유용한 데이터는 매우 드물다. 데이터를 저장하는 방법을 찾고 있습니다.
- 복제를 피하고 공간을 효율적으로 사용합니다 (현재 비원 표현은 저장하려는 데이터의 10% 미만에 260GB (데이터+색인)가 필요합니다).
- SQL 쿼리를 사용하여 특정 개정의 값을 효율적으로 검색 할 수 있습니다 (개정 또는 파일을 통해 명시 적으로 반복하지 않음).
- 특정 메트릭 값에 대한 개정을 효율적으로 검색 할 수 있습니다.
이상적으로는 솔루션이 특정에 의존해서는 안됩니다. RDBMS 그리고 호환되어야합니다 최대 절전 모드. 이것이 불가능한 경우, 최대 절전 모드, MySQL 또는 PostgreSQL 특이 적 기능을 사용하여 살 수 있습니다.
해결책
이것이 내가 그것을 모델링 할 수있는 방법입니다. 나는 개정 테이블과 파일 테이블을 제외했다.
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
제휴하지 않습니다 StackOverflow