Lors de l'accès / de la manipulation de données complexes, est-il préférable de les stocker en plusieurs petits morceaux ou en un gros morceau?

11

Je construis une application web qui manipule des données assez complexes: les tablatures de guitare.

    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-|

Serait-il plus efficace pour les performances de stocker ces données sous forme de gros morceaux, ou de les décomposer et de les stocker "note par note"?

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 je le stocke en bloc, le code pour manipuler les onglets devrait être beaucoup plus complexe. Si je le stocke note par note, la base de données devra être beaucoup plus accessible. Quelle méthode est la plus efficace? Potentiellement, de nombreux utilisateurs modifieront les données. Je veux l' application Web la plus performante. J'utiliserai MySQL si cela affecte la réponse.

Gabe Willard
la source
2
Mieux pour quoi? Économiser de l'espace? Puissance CPU? IO? Autre chose?
Oded
Eh bien, c'est une application Web. De nombreux utilisateurs vont potentiellement modifier les données assez fréquemment. J'imagine que beaucoup de facteurs comme vous le mentionnez affectent différemment. Je ne connais pas très bien ces détails; c'est en partie pourquoi je demande ici.
Gabe Willard
Si vous ne savez pas ce que vous optimisez, comment pouvons-nous répondre? La chose est - construisez-le d'abord, si vous avez des problèmes spécifiques, puis demandez comment les résoudre.
Oded le
12
Ne concevez-vous pas des bases de données avant de les créer? Ma question concerne la conception d'une base de données. Pas de dépannage. Je ne suis pas encore au stade du débogage, et même si je l'étais, cela irait à StackOverflow, pas aux programmeurs. Selon la FAQ: les programmeurs couvrent les concepts d'algorithme et de structure de données, les modèles de conception, l'architecture logicielle, l'ingénierie logicielle ... Pas le dépannage des goulots d'étranglement.
Gabe Willard
+1 problème très intéressant et bonne illustration de travail un cas d'utilisation utile. Cela me fait souhaiter d'avoir une bonne excuse pour développer une application de tablature de guitare maintenant.
Evan Plaice

Réponses:

8

Le nombre d'opérations va être le même de toute façon. Vous effectuez une requête pour obtenir tous les accords d'une chanson, puis vous effectuez une mise à jour chaque fois qu'un changement est effectué. La différence réside vraiment dans la taille des mises à jour. Avec la méthode du bloc, vous devez enregistrer la chanson entière à chaque fois que vous changez un accord. Avec la méthode individuelle, vos mises à jour seront plus petites et probablement plus efficaces dans l'ensemble, bien que la différence puisse être négligeable.

Une autre chose à considérer est que la méthode note par note est plus normalisée, ce qui signifie que vous aurez plus d'options de requête ouvertes si vous l'utilisez. Par exemple, les débutants peuvent filtrer les accords qu'ils ne connaissent pas lors de la recherche d'une chanson à apprendre, ou vous pouvez autoriser la recherche en fonction des accords d'ouverture si quelqu'un ne connaît pas le titre d'une chanson. Même si vous ne planifiez pas ces fonctionnalités maintenant, il sera très difficile de changer votre base de données si vous voulez quelque chose comme ça plus tard.

Karl Bielefeldt
la source
5

De manière générale, plus de normalisation est bonne pour plusieurs raisons:

  1. Moins de duplication des données, entraînant une taille de base de données physique plus petite.
  2. Meilleure intégrité des données - vous pouvez utiliser des clés étrangères pour appliquer certaines exigences.
  3. Code de mise à jour plus simple que vous avez identifié.
  4. Des voies d'accès plus indexables à des sous-ensembles de données.

Les inconvénients ( bien décrits ici ) comprennent:

  1. La normalisation économise de l'espace, mais l'espace est bon marché.
  2. La normalisation simplifie les mises à jour, mais les lectures sont plus courantes.
  3. Les performances sont généralement meilleures avec des schémas moins normalisés.

Je suggère de commencer avec une conception plus normalisée et de ne considérer la dénormalisation que si vous rencontrez des problèmes de performances.

Mike Partridge
la source
Avec la base de données des tablatures de guitare, la simplicité, la cohérence et l'intégrité l'emportent sur les performances. Je choisirais donc le schéma normalisé le plus simple possible.
9000
2

Rendez votre stockage plus facile à utiliser et assez dur à visser. Allez avec un schéma raisonnablement normalisé. Utilisez un schéma qui n'exclut pas les utilisations autres que celles dont vous aurez besoin dans votre première version, si possible.

Si tout ce dont vous avez besoin est d'afficher les onglets d'une chanson particulière, vous pouvez stocker de nombreux 6-tuples dans une base de données orientée document (comme MongoDB), en les récupérant comme un seul document.

Dans un SGBDR, je le stockerais de la même manière, dans une table comme celle-ci:

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)
)

Les SGBDR sont bons pour les requêtes simples comme celle nécessaire pour afficher une chanson:

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

À l'aide de limitet offset, vous pouvez afficher des parties d'une chanson.

Plus tard, il sera facile de créer tab_columnun lien vers un tableau qui répertorie les accords nommés, si vous pouvez reconnaître un accord.

Il s'agit probablement du schéma le plus simple possible; Je commencerais par ça.

9000
la source