Ao acessar / manipular dados complexos, é melhor armazená-los em vários pedaços pequenos ou em um pedaço grande?

11

Estou criando um aplicativo da web que manipula dados bastante complexos: abas 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-|

Seria mais eficiente para o desempenho armazenar esses dados como um bloco grande ou dividi-los e armazená-los "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|---

Se eu o armazenar como um bloco, o código para manipular as guias terá que ser muito mais complexo. Se eu guardar nota por nota, o banco de dados terá que ser acessado muito mais. Qual método é mais eficiente? Potencialmente, muitos usuários modificarão os dados. Quero o melhor aplicativo da web. Eu usarei o MySQL se isso afetar a resposta.

Gabe Willard
fonte
2
Melhor para quê? Economizando espaço? Poder da CPU? IO? Algo mais?
Oded
Bem, é um aplicativo da web. Muitos usuários estão modificando dados com bastante frequência. Eu imagino que muitos fatores, como você mencionou, afetam de maneira diferente. Eu não estou tão familiarizado com esses detalhes; é parcialmente por isso que estou perguntando aqui.
perfil completo de Gabe Willard
Se você não sabe o que está otimizando, como podemos responder? A coisa é - construa primeiro, se você tiver problemas específicos, depois pergunte como resolvê-los.
Oded
12
Você não cria bancos de dados antes de criá-los? Minha pergunta é sobre o design de um banco de dados. Não está solucionando um. Ainda não estou na fase de depuração e, mesmo que estivesse, isso iria para o StackOverflow, não para Programadores. De acordo com a FAQ: Programadores abordam conceitos de algoritmo e estrutura de dados, padrões de design, arquitetura de software, engenharia de software ... Não solucionando gargalos.
perfil completo de Gabe Willard
+1 problema muito interessante e boa ilustração do trabalho, um caso de uso útil. Faz-me desejar ter uma boa desculpa para desenvolver um aplicativo de guia de guitarra agora.
precisa

Respostas:

8

O número de operações será o mesmo de qualquer maneira. Você faz uma consulta para obter todos os acordes de uma música e faz uma atualização sempre que uma alteração é feita. A diferença está realmente no tamanho das atualizações. Com o método de bloqueio, você deve salvar a música inteira toda vez que alterar um acorde. Com o método individual, suas atualizações serão menores e provavelmente mais eficientes no geral, embora a diferença possa ser insignificante.

Outra coisa a considerar é que o método nota por nota é mais normalizado, o que significa que você terá mais opções de consulta abertas no futuro, se usá-lo. Por exemplo, iniciantes podem filtrar acordes que não conhecem ao pesquisar uma música para aprender, ou você pode permitir a pesquisa com base nos acordes de abertura, se alguém não conhece o título da música. Mesmo que você não planeje esses recursos agora, será muito difícil alterar seu banco de dados se você quiser algo assim mais tarde.

Karl Bielefeldt
fonte
5

De um modo geral, mais normalização é boa por vários motivos:

  1. Menos duplicação de dados, levando a um tamanho menor do banco de dados físico.
  2. Melhor integridade dos dados - você pode usar chaves estrangeiras para impor certos requisitos.
  3. Código de atualização mais simples, que você identificou.
  4. Rotas de acesso mais indexáveis ​​a subconjuntos de dados.

As desvantagens ( descritas bem aqui ) incluem:

  1. A normalização economiza espaço, mas o espaço é barato.
  2. A normalização simplifica as atualizações, mas as leituras são mais comuns.
  3. O desempenho geralmente é melhor com esquemas menos normalizados.

Eu sugeriria começar com um design mais normalizado e considerar apenas a desnormalização se você tiver problemas de desempenho.

Mike Partridge
fonte
Com o banco de dados de guias de guitarra, simplicidade, consistência e integridade superam o desempenho. Então, eu usaria o esquema normalizado mais simples que eu poderia criar.
9000
2

Torne seu armazenamento mais fácil de trabalhar e difícil o suficiente para estragar. Vá com um esquema razoavelmente normalizado. Siga um esquema que não exclua outros usos que você não precisará no seu primeiro release, se possível.

Se tudo o que você precisa é mostrar guias para uma música em particular, você pode armazenar muitas 6-tuplas em um banco de dados orientado a documentos (como o MongoDB), buscando-as como um único documento.

Em um RDBMS, eu o armazenaria de maneira semelhante, em uma tabela 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)
)

RDBMSes são bons em consultas simples como a necessária para mostrar uma música:

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

Usando limite offset, você pode mostrar partes de uma música.

Mais tarde, será fácil vincular tab_columna uma tabela que lista acordes nomeados, se você puder reconhecer um acorde.

Este é provavelmente o esquema mais simples possível; Eu começaria com isso.

9000
fonte