Question

J'ai un tableau représentant les valeurs des métriques du fichier source pour toutes les révisions du projet, comme suit:

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 vue relationnelle des données ci-dessus est différente. Chaque ligne contient les colonnes suivantes: Révision, FileId, Valeur. Les fichiers et leurs révisions à partir desquels les données sont calculées sont stockés dans des référentiels Subversion, nous essayons de représente la structure du référentiel dans un schéma relationnel.)

Il peut y avoir jusqu'à 23750 fichiers dans 10 000 révisions (c'est le cas de la ImageMagick programme de dessin). Comme vous pouvez le constater, la plupart des valeurs sont identiques entre les révisions successives, de sorte que les données utiles de la table sont relativement rares. Je cherche un moyen de stocker les données qui

  • évite la réplication et utilise efficacement l'espace (actuellement, la représentation non fragmentée nécessite 260 Go (données + index) pour moins de 10% des données que je souhaite stocker.
  • me permet de récupérer efficacement les valeurs d'une révision spécifique à l'aide d'une requête SQL (sans effectuer explicitement une boucle dans les révisions ou les fichiers)
  • me permet de récupérer efficacement la révision pour une valeur de mesure spécifique.

Idéalement, la solution ne devrait pas dépendre d'un SGBDR particulier et devrait être compatible avec < a href = "http://en.wikipedia.org/wiki/Hibernate_%28Java%29" rel = "nofollow noreferrer"> Hibernate . Si cela n’est pas possible, je peux utiliser les fonctionnalités spécifiques à Hibernate, MySQL ou PostgreSQL.

Était-ce utile?

La solution

Voici comment je pourrais le modéliser. J'ai laissé de côté le tableau des révisions et le tableau des fichiers, car ceux-ci devraient être assez explicites.

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

Pour obtenir toutes les valeurs des fichiers d’une révision particulière, vous pouvez utiliser la requête suivante. La jonction à la table des fichiers avec une jointure externe vous permet d’obtenir ceux qui n’ont pas de valeur définie pour cette révision.

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

En supposant que je comprenne bien ce que vous voulez dans votre troisième point, cela vous permettra d'obtenir toutes les révisions pour lesquelles un fichier particulier a une certaine valeur:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top