Quando si accede / manipola dati complessi, è meglio conservarli in molti piccoli pezzi o in un grosso blocco?


11

Sto costruendo un'app Web che manipola dati abbastanza complessi: tabulati per chitarra.

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

Sarebbe più efficiente per le prestazioni archiviare questi dati come un grosso blocco o suddividerli e archiviarli su una base "nota per 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 lo memorizzo come blocco, il codice per manipolare le schede dovrebbe essere molto più complesso. Se lo memorizzo nota per nota, sarà necessario accedere molto di più al database. Quale metodo è più efficiente? Potenzialmente, molti utenti modificheranno i dati. Voglio l' app Web con le migliori prestazioni. Userò MySQL se questo influisce sulla risposta.


2
Meglio per cosa? Risparmio di spazio? Potenza della CPU? IO? Qualcos'altro?
Oded,

Bene, è un'app Web. Molti utenti potrebbero modificare i dati abbastanza frequentemente. Immagino che molti fattori come quelli che hai menzionato influenzano diversamente. Non ho molta familiarità con quei dettagli; questo è in parte il motivo per cui lo sto chiedendo qui.
Gabe Willard,

Se non sai per cosa stai ottimizzando, come possiamo rispondere? Il punto è: crealo prima, se hai problemi specifici, quindi chiedi come risolverli.
Oded,

12
Non progettate database prima di costruirli? La mia domanda è sulla progettazione di un database. Non risolverne uno. Non sono ancora in fase di debug e, anche se lo fossi, andrebbe a StackOverflow, non ai programmatori. Per le domande frequenti: i programmatori coprono concetti di algoritmo e struttura dei dati, modelli di progettazione, architettura del software, ingegneria del software ... Non risolvere i colli di bottiglia.
Gabe Willard,

+1 problema molto interessante e buona illustrazione del lavoro un caso d'uso utile. Mi fa venire voglia di avere una buona scusa per sviluppare un'app per tablatura ora.
Evan Plaice,

Risposte:


8

Il numero di operazioni sarà lo stesso in entrambi i modi. Fai una query per ottenere tutti gli accordi di una canzone, quindi esegui un aggiornamento ogni volta che viene apportata una modifica. La differenza è davvero nella dimensione degli aggiornamenti. Con il metodo block, devi salvare l' intero brano ogni volta che cambi un accordo. Con il metodo individuale, i tuoi aggiornamenti saranno più piccoli e probabilmente nel complesso più efficienti, anche se la differenza potrebbe essere trascurabile.

Un'altra cosa da considerare è che il metodo nota per nota è più normalizzato, il che significa che avrai più opzioni di query aperte se lo usi. Ad esempio, i principianti potrebbero filtrare gli accordi che non conoscono durante la ricerca di una canzone da imparare, oppure potresti consentire la ricerca in base agli accordi di apertura se qualcuno non conosce il titolo di una canzone. Anche se non pianifichi queste funzionalità ora, sarà un grande problema cambiare il tuo database se vuoi qualcosa di simile in seguito.


5

In generale, una maggiore normalizzazione è buona per diversi motivi:

  1. Minore duplicazione dei dati, con conseguente riduzione delle dimensioni del database fisico.
  2. Migliore integrità dei dati: è possibile utilizzare chiavi esterne per applicare determinati requisiti.
  3. Codice di aggiornamento più semplice, che hai identificato.
  4. Percorsi di accesso più indicizzabili a sottoinsiemi di dati.

Gli svantaggi ( descritti bene qui ) includono:

  1. La normalizzazione consente di risparmiare spazio, ma lo spazio è economico.
  2. La normalizzazione semplifica gli aggiornamenti, ma le letture sono più comuni.
  3. Le prestazioni sono generalmente migliori con schemi meno normalizzati.

Suggerirei di iniziare con un design più normalizzato e prendere in considerazione la denormalizzazione solo se si verificano problemi di prestazioni.


Con database di tablature per chitarra, semplicità, coerenza e integrità vincono le prestazioni. Quindi andrei con lo schema normalizzato più semplice che potrei inventare.
9000,

2

Rendi il tuo spazio di archiviazione più facile da lavorare e abbastanza difficile da rovinare. Vai con uno schema ragionevolmente normalizzato. Scegli uno schema che non precluda usi diversi da quelli necessari nella prima versione, se possibile.

Se tutto ciò che serve è mostrare le schede per un particolare brano, è possibile memorizzare molte 6 tuple in un DB orientato al documento (come MongoDB), recuperandole come un unico documento.

In un RDBMS, lo memorizzerei in modo simile, in una tabella come questa:

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

Gli RDBMS sono bravi in ​​semplici query come quella necessaria per mostrare una canzone:

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

Usando limite offset, puoi mostrare parti di una canzone.

In seguito sarà facile collegarsi tab_columna una tabella che elenca gli accordi denominati, se è possibile riconoscere un accordo.

Questo è probabilmente lo schema più semplice possibile; Vorrei iniziare con questo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.