Pregunta

Tengo una tabla que representa los valores de las métricas del archivo de origen en las revisiones del proyecto, como las siguientes:

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 relacional de los datos anteriores es diferente. Cada fila contiene las siguientes columnas: Revisión, FileId, Valor. Los archivos y sus revisiones a partir de los cuales se calculan los datos se almacenan en repositorios de Subversion, por lo que estamos tratando de representar la estructura del repositorio en un esquema relacional).

Puede haber hasta 23750 archivos en 10000 revisiones (este es el caso de ImageMagick programa de dibujo). Como puede ver, la mayoría de los valores son los mismos entre revisiones sucesivas, por lo que los datos útiles de la tabla son bastante escasos. Estoy buscando una manera de almacenar los datos que

  • evita la replicación y utiliza el espacio de manera eficiente (actualmente, la representación no dispersa requiere 260 GB (datos + índice) para menos del 10% de los datos que quiero almacenar)
  • me permite recuperar de manera eficiente los valores para una revisión específica usando una consulta SQL (sin recorrer explícitamente las revisiones o los archivos)
  • me permite recuperar de manera eficiente la revisión para un valor métrico específico.

Idealmente, la solución no debería depender de un RDBMS en particular y debería ser compatible con < a href = "http://en.wikipedia.org/wiki/Hibernate_%28Java%29" rel = "nofollow noreferrer"> Hibernate . Si esto no es posible, puedo vivir usando las funciones específicas de Hibernate, MySQL o PostgreSQL.

¿Fue útil?

Solución

Así es como podría modelarlo. He omitido la tabla de revisiones y la tabla de archivos, ya que deberían explicarse por sí mismas.

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

Para obtener todos los valores de los archivos de una revisión en particular, puede usar la siguiente consulta. Unirse a la tabla de archivos con una combinación externa le permitiría obtener aquellos que no tienen un valor definido para esa revisión.

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

Suponiendo que entiendo correctamente lo que quiere en su tercer punto, esto le permitirá obtener todas las revisiones para las cuales un archivo en particular tiene un cierto valor:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top