Al acceder / manipular datos complejos, ¿es mejor almacenarlos en muchas piezas pequeñas o en un gran fragmento?

11

Estoy creando una aplicación web que manipula datos bastante complejos: pestañas de guitarra.

    As a reference, guitar tabs look like this:
Eb|-------------------------------------------------------------------------|
Bb|-------------------------------------------------------------------------|
Gb|--5-5-5-5----------------------------------------------------------------|
Db|--5-5-5-5--3-3-3-3--7-7-7-7--5-5-5-5--2-2-2-2--3-3-3-3--2-2-2-2--5-5-5-5-|
Ab|--3-3-3-3--3-3-3-3--7-7-7-7--5-5-5-5--2-2-2-2--3-3-3-3--2-2-2-2--5-5-5-5-|
Eb|-----------1-1-1-1--5-5-5-5--3-3-3-3--0-0-0-0--1-1-1-1--0-0-0-0--3-3-3-3-|

¿Sería más eficiente para el rendimiento almacenar estos datos como un gran fragmento, o dividirlos y almacenarlos "nota por nota"?

As a use case:
User changes first chord from:       to:
                         Eb|---   Eb|---
                         Bb|---   Bb|---
                         Gb|--5   Gb|--4
                         Db|--5   Db|--4
                         Ab|--3   Ab|--2
                         Eb|---   Eb|---

Si lo almaceno como un bloque, el código para manipular las pestañas tendría que ser mucho más complejo. Si lo guardo nota por nota, habrá que acceder a la base de datos mucho más. ¿Qué método es más eficiente? Potencialmente, muchos usuarios modificarán los datos. Quiero la mejor aplicación web. Usaré MySQL si eso afecta la respuesta.

Gabe Willard
fuente
2
¿Mejor para qué? ¿Ahorrando espacio? Potencia de la CPU? IO? ¿Algo más?
Oded
Bueno, es una aplicación web. Muchos usuarios potencialmente modificarán los datos con bastante frecuencia. Me imagino que muchos factores como el que mencionas lo afectan de manera diferente. No estoy tan familiarizado con esos detalles; eso es en parte por lo que pregunto aquí.
Gabe Willard
Si no sabe para qué se está optimizando, ¿cómo podemos responder? La cuestión es: compílelo primero, si tiene problemas específicos, luego pregunte cómo resolverlos.
Oded
12
¿No diseñas bases de datos antes de construirlas? Mi pregunta es sobre el diseño de una base de datos. No soluciono uno. Todavía no estoy en la etapa de depuración, e incluso si lo estuviera, iría a StackOverflow, no a los Programadores. Según las preguntas frecuentes: los programadores cubren conceptos de algoritmos y estructura de datos, patrones de diseño, arquitectura de software, ingeniería de software ... No solucionan problemas de cuellos de botella.
Gabe Willard
+1 problema muy interesante y buena ilustración de trabajo, un caso de uso útil. Me hace desear tener una buena excusa para desarrollar una aplicación de tablatura para guitarra ahora.
Evan Plaice

Respuestas:

8

El número de operaciones será el mismo en ambos sentidos. Hace una consulta para obtener todos los acordes de una canción, luego realiza una actualización cada vez que se realiza un cambio. La diferencia está realmente en el tamaño de las actualizaciones. Con el método de bloqueo, debe guardar la canción completa cada vez que cambia un acorde. Con el método individual, sus actualizaciones serán más pequeñas y probablemente más eficientes en general, aunque la diferencia puede ser insignificante.

Otra cosa a considerar es que el método nota por nota está más normalizado, lo que significa que tendrá más opciones de consulta abiertas en el futuro si lo usa. Por ejemplo, los principiantes pueden filtrar los acordes que no conocen cuando buscan una canción para aprender, o puede permitir la búsqueda en función de los acordes iniciales si alguien no conoce el título de una canción. Incluso si no planifica esas características ahora, será muy difícil cambiar su base de datos si desea algo así más adelante.

Karl Bielefeldt
fuente
5

En términos generales, una mayor normalización es buena por varias razones:

  1. Menos duplicación de datos, lo que lleva a un tamaño de base de datos físico más pequeño.
  2. Mejor integridad de los datos: puede usar claves externas para hacer cumplir ciertos requisitos.
  3. Código de actualización más simple, que has identificado.
  4. Más rutas de acceso indexables a subconjuntos de datos.

Las desventajas ( descritas bien aquí ) incluyen:

  1. La normalización ahorra espacio, pero el espacio es barato.
  2. La normalización simplifica las actualizaciones, pero las lecturas son más comunes.
  3. El rendimiento es generalmente mejor con esquemas menos normalizados.

Sugeriría comenzar con un diseño más normalizado, y solo considere desnormalizar si se encuentra con problemas de rendimiento.

Mike Partridge
fuente
Con la base de datos de tablaturas para guitarra, la simplicidad, la consistencia y la integridad triunfan sobre el rendimiento. Así que iría con el esquema normalizado más simple que se me ocurriera.
9000
2

Haga que su almacenamiento sea más fácil de trabajar y lo suficientemente difícil como para arruinarlo. Ve con un esquema razonablemente normalizado. Vaya con un esquema que no excluya otros usos de los que necesitará en su primer lanzamiento, si es posible.

Si todo lo que necesita es mostrar pestañas para una canción en particular, puede almacenar muchas tuplas en una base de datos orientada a documentos (como MongoDB), buscándolas como un documento.

En un RDBMS, lo almacenaría de manera similar, en una tabla como esta:

table tab_column (
  song_id integer not null foreign key references song(id),
  ordinal integer not null, -- position in the tabulature
  s1 number(2), -- position on 1st string
  ...
  s6 number(2),
  primary key(song_id, ordinal)
)

Los RDBMS son buenos para consultas simples como la que se necesita para mostrar una canción:

select * from tab_column
where song_id = :song_id
order by ordinal;

Usando limity offset, puede mostrar partes de una canción.

Más adelante, será fácil vincular tab_columna una tabla que enumere los acordes con nombre, si puede reconocer un acorde.

Este es probablemente el esquema más simple posible; Yo comenzaría con eso.

9000
fuente