2012-11-07 19 views
7

Quindi, per un certo numero di motivi, le associazioni polimorfiche sono considerate una cattiva progettazione del database, ad es. non è possibile avere chiavi esterne sulle colonne id polimorfiche, quindi l'integrità referenziale è scomparsa.Cosa usare invece di associazioni polimorfiche?

E, anche STI è considerato non valido a meno che i sottotipi differiscano solo per il comportamento.

Quindi la mia domanda è per Rails/ActiveRecord qual è il male minore nel seguente scenario:

ho bisogno di permettere ai miei utenti di creare un insieme ordinato mano di molteplici tipi di entità.

Utilizzando polimorfici associazioni lo schema sarebbe simile a questa:

-- collections 
id, name, ... 

-- exhibits 
id, collection_id, exhibitable_type, exhibitable_id, position 

-- photographs 
id, ... 

-- films 
id, ... 

-- paintings 
id, ... 

-- songs 
id, ... 

-- sculptures 
id, ... 

potrei usare STI e avere qualcosa di simile:

-- collections 
id, name, ... 

-- exhibits 
id, collection_id, artwork_id, position 

-- artworks 
id, type, <photograph columns>, <film columns>, <painting columns>, etc. 

Ma, perché le mie opere si differenziano su dati (e non solo comportamento), ora ho NULL su tutta la tabella delle opere d'arte. Ho anche introdotto una gerarchia di ereditarietà nei miei oggetti che prima non c'era e di solito sono cauto, in particolare quando il suo unico scopo è quello di servire la progettazione del database.

STI sembra che sarebbe per lo meno più semplice da interrogare e codificare.

Quindi qual è il male minore?

Poi, l'altra opzione è multi-ereditarietà delle tabelle:

-- collections 
id, name, ... 

-- exhibits 
id, collection_id, artwork_id, position 

-- artworks 
id 

-- photographs 
artwork_id, <photograph columns> 

-- films 
artwork_id, <film columns> 

Questo sarebbe sbarazzarsi di problema NULL di STI e anche mantenere la tabella dimensioni verso il basso. Abbiamo ancora una gerarchia di oggetti che non ritengo sia strettamente necessario. Ma il problema più grande nei miei occhi: Rails non lo supporta. La gemma CITIER sembra molto carina e ha recenti commit ma non è così ampiamente utilizzata, quindi sono prudente nell'utilizzarla nelle fondamenta della mia app. Immagino di poter anche usare Sequel o un altro ORM con supporto CTI.

A dire la verità penso che mi piace la soluzione multi-tavolo eredità il meglio

Se non ho bisogno la colonna posizione vorrei semplicemente utilizzare le tabelle unirsi separati come collections_photographs, collections_paintings, collections_films, ecc, ma io hanno bisogno di quell'ordinamento manuale.

Così, sembra che le opzioni sono:

  • PA: perdita di integrità referenziale (importa in pratica se sempre usando ActiveRecord per l'accesso al database?)
  • STI: grande tavolo con un sacco di null
  • CTI/MTI: basandosi su una gemma che non è ampiamente utilizzato

Qual è il male minore e ci sono altre opzioni? Sto usando Postgres.

risposta

1

Un'altra opzione è di normalizzare completamente la struttura del database e di avere viste per trasformare i dati in un modulo più adatto alle query.Non sono sicuro di quanto potrebbe funzionare con ORM diversi, quindi il tuo percorso potrebbe variare. In generale, ho trovato che è meglio basare il modello dei dati su come i dati sono strutturati in modo genuino in quanto ciò tende a prestarsi alla facilità di manutenzione. Dopo che i dati sono stati modellati correttamente, è possibile creare viste e stored procedure per accedere e manipolare i dati in modo conveniente.

0

È possibile implementare sia il polimorfismo sia le chiavi esterne se si utilizza uno partitioned table in Postgres, poiché le tabelle che rappresentano diverse partizioni possono rappresentare ciascuna un sottotipo diverso e ciascuna può avere un diverso insieme di vincoli.

Problemi correlati