Ottimizzazione delle prestazioni / integrità delle prestazioni dei dati nei database relazionali

3

Recentemente si è verificato uno scenario insolito durante la normalizzazione di un vecchio database relazionale.

I fatti

Ci sono ~ 8 tabelle collegate a una tabella centrale, in cui esistono riferimenti tra le numerose tabelle possono o meno .

Sono utilizzati molti dati e, sebbene questa tabella sia stata inizialmente progettata, creata e mutata nel tempo, le prestazioni sono state prese in considerazione. Quindi, non c'erano tabelle di collegamento fatte tra la centrale e l'ampli; altre tabelle.

Sto cercando di migliorare la struttura di questo, ma non di sacrificare le prestazioni della query, dal momento che le informazioni di tutte le tabelle possono essere utilizzate per la segnalazione.

Domanda: Come procedere nell'ottimizzazione / normalizzazione di una struttura di tabella come quella menzionata, senza sacrificare il fattore di prestazione?

Ho preso in considerazione le seguenti opzioni:

1 : l'aggiunta di tabelle di collegamento tra di loro renderebbe le query abbastanza avanzate, dove se viene eseguita una ricerca, tutte le tabelle pivot dovrebbero essere cercate per identificare qualsiasi relazione tra loro.

2 : aggiunta dell'ID della tabella centrale come indice sui tavoli esterni. Questa è un'idea, ma poi di nuovo, per trovare qualsiasi informazione, avresti bisogno di interrogare le altre tabelle. Per migliorare questo, aggiungere un campo di tipo di qualche tipo sulla voce della tabella centrale potrebbe aiutare a identificare le informazioni che esistono sui tavoli esterni.

Modifica - Esempio ERD

Ad esempio, considera un negozio di riparazioni di computer. Ai fini dell'esempio, vengono fatte le seguenti ipotesi:

  • Questo è un piccolo sottosistema, un cliente potrebbe essere entrato per comprare un ventilatore RGB e non ha portato un dispositivo. Quindi, i clienti non devono avere un dispositivo cliente
  • Quando si esegue una riparazione e viene registrata un'Attività di riparazione, il cliente potrebbe richiamarla per qualsiasi motivo.
  • Per ogni RepairActivity, è possibile visualizzare una relazione 1 a 1 tra la tabella WorkInformation.
  • Un RepairInvoice viene generato solo quando il cliente entra nello store, quindi, un'Attività Repair può esistere senza uno.
  • Un Cliente può avere un Dispositivo Cliente registrato sul sistema e non averlo portato per una riparazione.

Questo è un esempio di base e il sistema menzionato nella domanda ha molte più tabelle allegate.

    
posta N15M0_jk 09.03.2017 - 14:24
fonte

1 risposta

1

Ottima prima domanda e benvenuto.

Risposta breve:

Fai in modo che ogni tabella abbia un PK, che ci sia un FK per ogni relazione e che aggiunga indici alle colonne che verranno interrogate spesso, e crei viste che ti astraggono dai join se non vuoi dire che si unisce ogni tempo. Le prestazioni saranno buone. RDBMS sono ottimizzati per fare esattamente questo.

Risposta lunga che include alcune basi di osservazioni su informazioni limitate:

  1. WORK_INFORMATION e REPAIR_ACTIVITY aventi una relazione 1: 1, hanno un alto cambiamento di essere la stessa entità. Una possibile eccezione è se WORK_INFORMATION ha colonne che non si applicano a tutti REPAIR_ACTIVITY s, ma, data la relazione è 1: 1, vorrei considerare se dovrebbero essere o meno due tabelle separate. Inoltre, le relazioni 1: 1 sono concettualmente possibili, ma non fisicamente poiché non è possibile inserire in una delle due tabelle finché non esiste una wor corrispondente nell'altra ... a meno che non si imponga l'integrità completamente nel codice e non si utilizzino i vincoli del database.

  2. "Aggiunta dell'ID della tabella centrale come indice sui tavoli esterni." In primo luogo, assumerò che ciò che chiami "tabella centrale" sia% codice%. Bene, quelle tabelle che hanno una relazione con REPAIR_ACTIVITY dove REPAIR_ACTIVITY è su un lato della relazione, dovrebbero già avere il PK di REPAIR_ACTIVITY come una colonna, cioè una chiave esterna che punta a REPAIR_ACTIVITY , e tutte FK sono indicizzati. Le tabelle che hanno una relazione con REPAIR_ACTIVITY in cui REPAIR_ACTIVITY si trova su molti lati della relazione non devono avere una colonna con l'ID REPAIR_ACTIVITY . Ciò sarebbe fisicamente impossibile poiché potrebbe esserci un solo valore su qualsiasi riga in un lato, rendendo la relazione 1: 1.

  3. Vorrei controllare la relazione tra REPAIR_ACTIVITY e REPAIR_INVOICE . La relazione è invertita (cioè REPAIR_ACTIVITY dovrebbe essere il primo e REPAIR_INVOICE i molti)? In caso contrario, ignorare questo suggerimento e cancellarlo per mancanza di informazioni.

  4. "... l'aggiunta di un campo tipo di qualche tipo sulla voce della tabella centrale potrebbe aiutare a identificare le informazioni che esistono sui tavoli esterni" che in alcuni casi non è necessario e in altri casi impossibili, se ciò che ti preoccupa è la complessità delle query fai questo: crea viste dove ti unisci già alle tabelle. Quindi nel tuo codice chiedi quelle viste. In questo modo non dovrai scrivere i join ogni volta, solo la parte REPAIR_ACTIVITY per filtrare la selezione.

  5. Per quanto riguarda il rendimento , aggiungere tabelle di join laddove sono necessarie, non dovrebbe danneggiare le prestazioni se tutte le tabelle hanno un PK, c'è un FK per ogni relazione e ci sono indici su quelle colonne che verrà interrogato spesso (PK e FK hanno già indici).

risposta data 10.03.2017 - 13:45
fonte

Leggi altre domande sui tag