6

La mia applicazione carica molti dati da un database in una struttura dati complessa. La in memoria struttura dati ressembles la struttura del database, il che significa che se il database contiene le seguenti tabelle:Dipendenze circolari in chiavi esterne: usarlo o evitarlo?

  • tabella A, chiave è A1
  • tabella B, chiave è B1, una delle colonne è una chiave esterna [la chiave] tabella a
  • tabella C, chiave è C1, una delle colonne è una chiave esterna [la chiave] tabella B

Poi devo classi a, B e C, e:

  • un membro di dati di B (B :: m_A) è un puntatore a una
  • un membro di dati di C (C :: m_B) è un puntatore a B

Ciò implica che se carico il database, che devo caricarlo nell'ordine corretto. Se prima carico C, allora si lamenterà che non può impostare il valore C :: m_b perché l'istanza in cui dovrebbe puntare non è stata caricata.

problema è quando c'è anche una colonna in una che è una chiave esterna per uno degli altri tavoli, diciamo C.

ho potuto risolvere il problema caricando tutte le chiavi esterne come stringhe, e quindi eseguire una ricerca dopo che tutti i dati sono stati caricati, ma dato che a volte devo caricare milioni di record, non posso permettermi di spendere la memoria su queste (sebbene temporanee) stringhe.

Dopo aver letto del buon design (ad esempio il libro "Progettazione software C++ su larga scala") mi sembra che sia una cattiva idea avere riferimenti circolari. E.g. se il file X.H include Y.H, ma Y.H include anche X.H probabilmente hai un design errato; se la classe X dipende dalla classe Y e viceversa probabilmente hai un design errato, che dovrebbe essere risolto estraendo questa dipendenza e introducendo una terza classe Z, che dipende da X e Y (X e Y non dipenderanno più da nessuno) .

È consigliabile estendere questa regola di progettazione alla progettazione del database? In altre parole: prevenzione di riferimenti circolari in chiavi esterne.

risposta

3

L'unica volta che è necessario un riferimento circolare è quando si crea una struttura gerarchica, ad esempio un albero organizzativo.

Table Employees 
    EmployeeID <----------| 
    SupervisorEmployeeID ---| 
2

Sì, le dipendenze cicliche nei database sono una buona scusa per ripensare il progetto.

+0

Perché? Non fornisci alcuna giustificazione per la tua affermazione. – cdmckay

4

Da un punto di vista della modellazione dei dati non c'è nulla di fondamentalmente "sbagliato" con una dipendenza da circolarità. Ciò non significa che il modello sia sbagliato.

Sfortunatamente la maggior parte dei DBMS SQL non è in grado di implementare tali vincoli in quanto non supportano più aggiornamenti di tabella. Solitamente l'unico modo per aggirare questo è sospendere temporaneamente uno o più vincoli (ad esempio usando una chiave esterna "deferrabile" o caratteristiche simili) o alterando il modello per rendere facoltativa una parte del vincolo (mettendo una delle colonne di riferimento in un nuova tabella). Questo è solo un modo per ovviare a una brutta limitazione di SQL, tuttavia, non significa che tu abbia fatto qualcosa di sbagliato all'inizio.

2

Devi modellare i dati che hai.Se c'è una relazione circolare nei dati (ad esempio ogni foto appartiene a una cartella, ma ogni cartella ha una foto di copertina), è corretto modellarla come una relazione circolare nel database.

Ho avuto questa situazione solo una volta quando uso Oracle, quindi non ho avuto la possibilità di verificare come implementare tale relazione su altri database. Ma per Oracle puoi leggere il mio articolo qui:

http://www.databasesandlife.com/circular-dependencies-on-foreign-key-constraints-oracle/