Domanda

Ho una tabella che rappresenta i valori delle metriche del file sorgente attraverso le revisioni del progetto, come il seguente:

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

(La vista relazionale dei dati sopra è diversa. Ogni riga contiene le seguenti colonne: Revisione, FileId, Valore. I file e le loro revisioni da cui vengono calcolati i dati sono memorizzati nei repository Subversion, quindi stiamo provando a rappresenta la struttura del repository in uno schema relazionale.)

Possono esserci fino a 23750 file in 10000 revisioni (questo è il caso del ImageMagick programma di disegno). Come puoi vedere, la maggior parte dei valori sono gli stessi tra le revisioni successive, quindi i dati utili della tabella sono piuttosto scarsi. Sto cercando un modo per archiviare i dati che

  • evita la replica e utilizza lo spazio in modo efficiente (attualmente la rappresentazione non sparsa richiede 260 GB (dati + indice) per meno del 10% dei dati che voglio archiviare)
  • mi consente di recuperare in modo efficiente i valori per una revisione specifica utilizzando una query SQL (senza scorrere esplicitamente le revisioni o i file)
  • mi consente di recuperare in modo efficiente la revisione per un valore di metrica specifico.

Idealmente, la soluzione non dovrebbe dipendere da un particolare RDBMS e dovrebbe essere compatibile con < a href = "http://en.wikipedia.org/wiki/Hibernate_%28Java%29" rel = "nofollow noreferrer"> Hibernate . Se ciò non è possibile, posso convivere con le funzionalità specifiche di Hibernate, MySQL o PostgreSQL.

È stato utile?

Soluzione

Ecco come potrei modellarlo. Ho tralasciato la tabella Revisioni e la tabella File poiché dovrebbero essere abbastanza autoesplicative.

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

Per ottenere tutti i valori per i file di una particolare revisione è possibile utilizzare la seguente query. Partecipare alla tabella dei file con un join esterno ti permetterebbe di ottenere quelli che non hanno un valore definito per quella revisione.

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

Supponendo che io capisca correttamente cosa vuoi nel tuo terzo punto, questo ti permetterà di ottenere tutte le revisioni per le quali un determinato file ha un certo valore:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top