Devo creare una tabella separata per ogni tipo derivato?

1

Stiamo discutendo e sto lottando per decidere da che parte scendere. Fondamentalmente abbiamo un tipo di evento che diciamo in questo modo (esempio semplificato).

public class Event
{
    public virtual int EventId { get; set; }
    public virtual DateTime DateTimeOccurred { get; set; }
}

Molti eventi diversi nel nostro sistema possono ereditare da questo così potremmo avere:

public class UserUpdatedEvent : Event
{
    public virtual User User { get; set; }
}

Quindi in pratica qualsiasi evento può ereditare dall'evento di base e quindi possiamo tenere traccia di ciò che sta accadendo nel nostro sistema che dobbiamo fare mentre le attività si verificano da questi eventi, ecc.

La mia domanda è che dovremmo avere una tabella nel DB per ogni evento in modo che possiamo applicare chiavi esterne in questo esempio all'utente utilizzando la tabella per tipo con ogni sottotipo che fa riferimento alla tabella degli eventi di base. O dovremmo avere una singola tabella e una colonna, magari un link a un enum che dice quale sia l'evento e quindi un'altra colonna contenente la chiave primaria per quell'oggetto ma non saremo in grado di imporre l'integrità referenziale (magari con un trigger ma non ideale e non a prova di tutto).

I professionisti per una singola tabella sono la velocità, nessun join, più semplice da costruire / mantenere, ecc. I contro non sono integrità referenziale, stiamo usando EF e la tabella per tipo funziona molto bene, d'altra parte produciamo un molti report e questi sono sprocs SQL diretti per la velocità e i join diventeranno piuttosto pesanti.

In che modo le persone di solito scendono in una situazione come questa?

Grazie mille per eventuali approfondimenti sui sistemi esistenti con problemi simili e aiutandoci a risolvere questa decisione.

    
posta user351711 12.04.2013 - 13:49
fonte

4 risposte

3

Una singola tabella è un buon approccio quando le sottoclassi non hanno molti attributi o associazioni con altre classi.

Altrimenti la tabella sarà piena di attributi che hanno senso solo per alcune righe e dovrai aggiungere tutti i tipi di vincoli per controllare che contengano solo valori per le righe del "tipo" appropriato.

Come stai suggerendo, questo è davvero un compromesso e dovresti valutare i vantaggi e gli svantaggi di entrambe le soluzioni.

Un altro approccio che non hai menzionato può essere quello di usare una tabella per tipo e non usare affatto una tabella comune. In questo modo è necessario ripetere le colonne nelle diverse tabelle.

  • Puoi avere integrità referenziale
  • Non hai bisogno di join per recuperare le informazioni per gli eventi (a livello di riga).
  • Non è necessario il rilevamento dei tipi nell'applicazione poiché si conosce la tabella su cui si sta eseguendo la query.

Naturalmente questo ha anche alcuni svantaggi:

  • Chiave univoca di un evento: dal momento che vivono in diverse tabelle non è possibile utilizzare un numero autonome. È possibile aggirare questo problema utilizzando un GUID come chiave univoca.
  • Interrogazione di un evento di cui non conosci il tipo.
  • Per interrogare tutti gli eventi è necessaria una query per tabella.

Alla fine non esiste una soluzione "migliore", c'è solo una soluzione migliore per il tuo caso. Tu sei l'unico che ha tutti i dati e le informazioni necessarie per prendere questa decisione.

    
risposta data 12.04.2013 - 14:02
fonte
0

Dovrò dissapoint tu, ma non esiste una semplice regola del pollice che ti dice come modellare l'ereditarietà di un oggetto in un database relazionale. Tuttavia le soluzioni ampiamente utilizzate sono ben documentate ed è facile trovare buoni articoli su di loro che elencano i pro ei contro. I termini comunemente usati per le tue soluzioni proposte sono (la ricerca sarà più efficiente usando questi):

  • Utilizzo di una tabella: ereditarietà di una tabella
  • Tabelle multiple: ereditarietà delle tabelle delle classi

Altre soluzioni che non hai menzionato nella tua domanda:

  • Ereditarietà della tabella concreta
  • Utilizzo dei dati semistrutturati

Devi considerare tutti i pro e i contro per decidere quale si adatta meglio al caso specifico.

    
risposta data 12.04.2013 - 14:07
fonte
0

Puoi avere una colonna XML addizionale che conterrà tutti i requisiti dei dati aggiuntivi per le classi ereditate. Questa potrebbe essere l'opzione di molte varianti che non puoi gestire usando le tabelle.

    
risposta data 12.04.2013 - 15:05
fonte
0

Vorrei dividere le proprietà degli oggetti in due tabelle.

Una tabella contiene gli attributi "core" comuni a tutte le classi e definiti in Event. Una tabella classica con una colonna per proprietà.

Una seconda tabella contiene tutte le proprietà che sono diverse da quelle comuni. Sono memorizzati in una tabella con il tipo di colonne, id, chiave, valore. (tipo è facoltativo ma può aiutarti a ottimizzare le tue query)

Vedi EAV (valore dell'attributo dell'entità)

    
risposta data 17.04.2013 - 14:44
fonte

Leggi altre domande sui tag