Domanda

Sto usando Firebird 2.1 e sto cercando il modo migliore per risolvere questo problema.

Sto scrivendo un'applicazione di calendario.Le voci del calendario di diversi utenti sono archiviate in una grande tabella del calendario.Ciascuna voce del calendario può avere un promemoria impostato: solo un promemoria/voce.

Statisticamente, la tabella Calendario potrebbe crescere fino a raggiungere centinaia di migliaia di record nel tempo, mentre ci saranno molti meno promemoria.

Ho bisogno di interrogare i promemoria su base costante.

Qual è l'opzione migliore?

A) Memorizza le informazioni sui promemoria nella tabella Calendario (nel qual caso interrogherò centinaia di migliaia di record per IsReminder = 1)

B) Crea una tabella Promemoria separata che contiene solo l'ID delle voci del calendario con promemoria impostati, quindi interroga le due tabelle con un'operazione JOIN (o magari crea una vista su di esse)

C) Posso memorizzare tutte le informazioni sui promemoria nella tabella Promemoria, quindi interrogare solo questa tabella.Lo svantaggio è che alcune informazioni devono essere duplicate in entrambe le tabelle, ad esempio per mostrare il promemoria dovrò conoscere e memorizzare l'ora di inizio dell'evento nella tabella Promemoria, quindi mantengo due tabelle con gli stessi valori.

Cosa ne pensi?

E ancora una domanda:La tabella Calendario conterrà il calendario di più utenti, separati solo da un campo UserID.Poiché possono esserci solo 4-5 utenti, anche se inserisco un indice in questo campo, la sua selettività sarà pessima, il che non va bene per una tabella con centinaia di migliaia di record.C'è una soluzione alternativa qui?

Grazie!

È stato utile?

Soluzione

Ci sono vantaggi e svantaggi in tutte e tre le scelte.Qual è il migliore dipende dai dettagli che non hai fornito.In generale, non preoccupatevi troppo di selezionare tre o quattro voci su centomila, purché gli indici che avete impostato consentano la giusta strategia di recupero.Se non capisci l'indicizzazione, probabilmente sarai nei guai, indipendentemente da quale delle tre scelte farai.

Se fossi in me opterei per la scelta B.Memorizzerei anche tutti gli attributi di un promemoria nella tabella per i promemoria.

Fai molta attenzione se identifichi un evento solo tramite EventId o tramite (UserId, EventId).Se scegli quest'ultimo, è necessario utilizzare una chiave primaria composta per la tabella Eventi.Non preoccuparti troppo delle chiavi primarie composte, specialmente con Firebird.
Se dichiari una chiave primaria composta, tieni presente che la dichiarazione di (UserId, EventId) non avrà le stesse conseguenze della dichiarazione di (EventId, UserId).Sono logicamente equivalenti, ma la struttura dell'indice generato automaticamente sarà diversa nei due casi.

Ciò a sua volta influenzerà la velocità delle query come "trova tutti i promemoria per un determinato utente".

Ancora una volta, se fossi in me, eviterei la scelta C.l'introduzione di ridondanze dannose in uno schema porta con sé la responsabilità di una programmazione molto attenta quando si vanno ad aggiornare i dati.Altrimenti ci si può ritrovare con un database che memorizza versioni contraddittorie dello stesso fatto in punti diversi del database.

E, se vuoi davvero conoscere l'effetto sulle prestazioni, prova tutti e tre i modi, carica i dati dei test ed esegui i tuoi benchmark.

Altri suggerimenti

Credo che è necessario creare, falsi dati utente realistici e misurare la differenza con alcune query tipici che ci si aspetta da eseguire.

Indicizzazione, ottimizzazione delle query e le tipologie di risultati della query è necessario può fare una grande differenza, quindi non è facile dire cosa è meglio senza sapere di più.

Al momento di scegliere Opzione (A) si dovrebbe

  • fornire un indice su "IsReminder" (o di un indice combinato su IsReminder, UserId, qualunque cosa si adatta meglio alle vostre domande destinate)
  • Assicurati che il tuo query utilizzano questo indice

L'opzione B è preferibile rispetto A se si dispone di più di un flag booleano per ogni sollecito da memorizzare (ad esempio, il numero di minuti che l'utente deve essere avvisato prima dell'evento). Si dovrebbe, tuttavia, fare un po 'di indovinare quante volte nel programma si dovrà unirsi entrambe le tabelle.

Se è possibile, evitare di opzione C. Se non si desidera di riferimento tutti e tre i casi, vi consiglio di iniziare con A o B, a seconda delle circostanze descritte, e, probabilmente, la soluzione che si sceglie sarà abbastanza veloce, in modo da non c'è bisogno di perdere tempo con gli altri casi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top