tabella singola con colonne aggiuntive rispetto a più tabelle che duplicano lo schema


13

Sto lavorando a un progetto in cui, a un certo punto, dovevo prendere una decisione sull'opportunità o meno, nel database, di avere una singola tabella con più colonne che non tutti i record utilizzano o più tabelle con schema duplicato.

Sto creando un'applicazione di informazioni sportive in grado di gestire più sport. Possiamo gestire NBA, NHL, MLB, NFL per esempio. Ogni sport ha concetti molto simili: squadre, orari, infortuni, informazioni sul giocatore.

La nostra fonte di dati ovviamente non ci fornisce ogni dato nello stesso schema. Ogni sport ha uno schema diverso a cui riceviamo i dati dal nostro fornitore.

Poiché non c'era abbastanza tempo (richieste del cliente) per fare analisi anticipate dei feed di dati per determinare i punti in comune, ho coperto la mia scommessa e preso la "scommessa sicura" e ho creato singoli tavoli separati per ogni sport anziché un set di tavoli che tutti sport usati.

Il risultato è uno schema duplicato in diverse tabelle e quindi anche interfacce duplicate al database (ad es. Proc memorizzati). Ho qualcosa come NBA_Game, NFL_Game, NBA_Team, NFL_Team, ecc. Ogni tabella potrebbe avere alcune proprietà che l'altra non ha, e molte che sono condivise. continua per dire 5-10 tavoli su 4 o 5 sport. Non sono ancora sicuro che questa sia una cosa completamente negativa: l'alternativa, con un singolo set di tavoli che aveva proprietà su di esso che non tutti gli sport avrebbero usato, potrebbe essere stata ingombrante anche da sola.

Qualcuno che ha fatto questo ha incontrato insidie ​​di questo tipo di design e potrebbe condividere la sua esperienza qui? Cose che potrebbero aiutarmi a sapere ora invece di imparare a fondo in fondo alla strada? Hai fatto diversamente, avendo una grande tabella / serie di tabelle, con colonne che non tutti i record userebbero? Quali insidie ​​hai incontrato per farlo?

Esiste un'alternativa come l' ereditarietà delle tabelle che hai usato in passato che ha funzionato meglio?

Grazie

Risposte:


12

In definitiva, si riduce all'uso e all'architettura.

Architettura

Il sistema gestisce "qualsiasi sport"? L'idea di indossare il tuo cappello da astronauta in architettura e costruire un sistema generico in grado di gestire qualsiasi tipo di sport futuro che potrebbe non esistere oggi?

In tal caso, ovviamente avere tabelle con nomi dinamici è una vera seccatura, quindi avrebbe senso avere uno schema che supporti n sport, se necessario.

Detto questo, ho un forte pregiudizio nei confronti di questo approccio: questo è quasi sempre più lavoro e porta a risultati più scarsi. Fare un'interfaccia utente, uno schema, ecc. Separati per ogni sport alla fine porterà a una migliore esperienza utente e a mantenere più facilmente il codice, anche se ciò significa una quantità superficiale di duplicazione (come evitare / minimizzare questa è una domanda separata).

Come gestisci i giocatori che praticano più sport? Ricevono due voci (ad esempio, trattate come persone diverse) o state provando a fare qualcosa di specifico con loro?

Uso

Quindi supponiamo che tu non pratichi sport in modo dinamico (ad esempio, se qualcuno vuole aggiungere un nuovo sport, è necessario uno sforzo di sviluppo per aggiungerlo).

C'è mai un momento in cui stai mostrando giocatori (o qualsiasi altro oggetto che hai citato) di più di uno sport alla volta?

Potrei vedere questo per una funzione di ricerca, in cui puoi cercare per nome del giocatore o della squadra (indipendentemente dallo sport), ma oltre a ciò non riesco a immaginare molti casi d'uso.

Se non hai mai bisogno di farlo, il tuo approccio è perfetto. Puoi smettere di leggere qui.

Schemi alternativi

Visualizzazioni

Sono un fan di KISS. In oltre 15 anni di sviluppo software, continuo a ripiegare sulla filosofia "costruire la cosa più semplice che funzioni".

Quindi la mia reazione iniziale, supponendo che una funzione di ricerca cross-sport sia davvero l'unico caso d'uso, è quella di creare viste:

SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

Naturalmente, se aggiungi un nuovo sport, devi aggiungere alla vista. Può anche essere utile includere altre informazioni comuni, ma in realtà dipende da ciò che deve essere mostrato.

Proverei a mantenere tutte le cose specifiche per lo sport nella definizione di visualizzazione, quindi il codice di ricerca non ha bisogno di avere molto o alcun codice specifico (oltre a forse sapere come collegarsi a /nhl/players/player-namevs /nfl/...o comunque la tua app lo fa).

Ereditarietà della tabella

L'ereditarietà delle tabelle può funzionare, ma è piuttosto complessa. Non ho molta esperienza con esso, e in effetti, penso che ogni volta che sono stato coinvolto nella valutazione, abbiamo finito per fare qualcosa di più semplice (come sto suggerendo qui).

Quindi, personalmente, devo ancora scoprire perché questo sarebbe utile, ma forse esiste un caso d'uso convincente (che non conosco) che giustifica la complessità (ad esempio, l'ereditarietà delle tabelle risolve il caso d'uso meglio di qualsiasi altra soluzione) .

Tabelle separate per attributi specifici dello sport

Potresti creare un singolo playerstavolo con attributi comuni a tutti i giocatori di tutti gli sport, e quindi un altro set di tavoli come nhl_players_detailsquello contiene un ID giocatore e colonne con informazioni aggiuntive sul giocatore. Se ci sono un sacco di attributi comuni, o hai molti usi di "tutti i giocatori di tutti gli sport", allora potrebbe avere senso.

Coppie chiave-valore per attributi specifici dello sport

Approccio completamente alternativa: avere un playerstavolo (di nuovo, con gli attributi comuni come nome) e poi una player_datatabella che ha PlayerId, Sport, Attribute, Value. I nomi degli attributi immessi sarebbero specifici per lo sport. Ciò consente essenzialmente di aggiungere nuovi attributi senza modificare lo schema (il codice dovrebbe comunque sapere per caricarli / visualizzarli ovviamente). Lo svantaggio è che perdi un po 'di integrità: il valore sarebbe in genere un campo stringa, quindi il codice dell'app dovrebbe essere resiliente e gestire potenziali errori convertendo la stringa valuein un tipo di dati specifico (come intero).

Questo concetto può ovviamente applicarsi a squadre, giochi, ecc.


La ricerca di una soluzione per un progetto legacy comporterà più tipi e tabelle autenticabili, la menzione di punti di vista qui, che avevo dimenticato, mi ha davvero aiutato a offrire un'altra possibile soluzione alla mia ricerca. Grazie.
FullStackFool

5

Stai parlando di normalizzazione del database . Potresti essere sollevato nell'apprendere che non esiste un modello di dati perfetto e che una maggiore normalizzazione non è sempre migliore. La normalizzazione può comportare costi in termini di chiarezza del modello di dati e delle prestazioni del database. Pertanto, il modello migliore da selezionare dipenderà dai requisiti di utilizzo.

A prima vista, i tuoi esempi sembrano abbastanza simili nel concetto (X_Game vs Y_Game e X_Team vs Y_Team) che l'overhead aggiuntivo di alcune colonne non sembra irragionevole. Detto questo, se ogni sport aggiungesse diverse dozzine di colonne extra al tavolo, sarebbe davvero ingombrante.

In tal caso, potresti prendere in considerazione un modello ibrido, in cui i dati comuni sono conservati in una tabella centrale, ma i dati specifici dello sport vengono conservati in una struttura di dati collegata. Qualcosa di simile a:

table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}

Questo è quello che stavo per proporre, più forse una colonna nella tabella del Gioco che indica il tipo di gioco. Mi rendo conto che si può dedurre unendo gli altri tavoli, ma se il numero di tipi di gioco aumenta, questo inizia a diventare noioso.
Rory Hunter,

Assolutamente: questo è solo un modello di scheletro per illustrare le relazioni fondamentali e alcuni esempi di quali potrebbero essere i dati comuni rispetto ai dati specifici dello sport.
Midnotion,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.