È un modo ridicolo per strutturare uno schema DB o mi manca qualcosa?

61

Ho svolto un bel po 'di lavoro con i database relazionali e penso di capire abbastanza bene i concetti di base del buon schema. Recentemente ho avuto il compito di rilevare un progetto in cui il DB è stato progettato da un consulente altamente pagato. Per favore fatemi sapere se il mio istinto intestinale - "WTF ??!?" - è giustificato, o questo ragazzo è un genio che sta operando fuori dal mio regno?

Il DB in questione è un'app interna utilizzata per immettere richieste dai dipendenti. Basta guardare una piccola parte di esso, si dispone di informazioni sugli utenti e informazioni sulla richiesta effettuata. Lo disegnerei in questo modo:

Tabella utente:

UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department

Tabella richieste

RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table

Semplice, vero?

Il consulente l'ha progettato in questo modo (con dati di esempio):

UsersTable

UserID  FirstName   LastName
234     John        Doe
516     Jane        Doe
123     Foo         Bar

DepartmentsTable

DepartmentID   Name
1              Sales
2              HR
3              IT

UserDepartmentTable

UserDepartmentID   UserID   Department
1                  234      2
2                  516      2
3                  123      1

RequestTable

RequestID   UserID   <...>
1           516      blah
2           516      blah
3           234      blah

L'intero database è costruito in questo modo, con ogni pezzo di dati incapsulato nella propria tabella, con ID numerici che collegano tutto insieme. Apparentemente il consulente aveva letto su OLAP e voleva la "velocità delle ricerche per interi"

Ha anche un gran numero di stored procedure per fare riferimento a tutte queste tabelle.

Questa progettazione valida è per un DB SQL di piccole e medie dimensioni?

Grazie per i commenti / le risposte ...

    
posta Jim 29.09.2011 - 18:45
fonte

6 risposte

72

Ha perfettamente senso per me. È solo molto normalizzato, che conferisce molta flessibilità che altrimenti non avresti. I dati de-normalizzati sono un dolore nel sedere.

    
risposta data 29.09.2011 - 18:52
fonte
48

Non penso che un WTF sia giustificato o che il ragazzo stia facendo un pazzo genio di design - è una normalizzazione del database piuttosto standardizzata.

Il motivo per la tabella di dipartimento è che se non si mettono i reparti in una tabella separata, si dovrà trattare con gli utenti in "Vendite", "vendite", "Venditori", "Vele" e "Vendita" "dipartimenti, a meno che tu non faccia qualcosa per impedirlo. E avere la tabella extra è (parte) il modo migliore che conosco per farlo.

Se ci dovrebbe essere una tabella UserDepartment è una chiamata più dura, il che significa che nessuna delle due decisioni è pazzesca. Da un lato è un dolore quando il design e la logica di tutti i tavoli hanno assunto un reparto per utente e quindi i cambiamenti, d'altra parte fare un join extra senza motivo per anni e anni è una possibilità reale e anche un dolore. / p>

Personalmente sono d'accordo con te sul fatto che la tabella UserDepartment è probabilmente eccessiva. Anche se è incluso, è probabile che nel tempo le persone scriveranno query che presuppongono che ci sia un solo utente per reparto, così finirai con il peggiore dei due mondi - un join extra senza motivo prima di aver bisogno del tavolo, e il codice non funziona comunque una volta più di un reparto per utente è consentito.

EDIT - Un driver chiave per stabilire se la relazione da molti a molti debba essere supportata è se le regole aziendali sono chiare. Se non hai idea di come possa funzionare un utente in più reparti, non è molto utile aggiungere la tabella, poiché il tuo codice non può gestire correttamente i casi in cui un utente si trova in più reparti.

Immagina di aver permesso a molti reparti per utente, per ogni evenienza. Hai quindi implementato una regola aziendale per l'assegnazione delle commissioni, in base al reparto. Quindi sono stati autorizzati più dipartimenti. Fortunatamente, hai avuto anche la lungimiranza di scrivere il codice della commissione in un modo che ne tenesse conto. Sfortunatamente, hai aggiunto le commissioni di ciascun dipartimento per gli utenti di entrambi. La direzione voleva che vi basaste sul ruolo delle persone per ogni vendita. Quindi, quanto è stato bello avere il tavolo in anticipo? Che dire degli altri tavoli che avevi "solo nel caso" che non sono mai necessari?

LATER EDIT - Un altro motivo per cui il consulente potrebbe aver voluto aggiungere tutte quelle tabelle intermedie è affrontato in questa domanda di follow-up , le cui risposte forniscono alcuni motivi per cui il refactoring di un database è solitamente più difficile del codice refactoring, che tenderebbe a spingerti verso il" put " in tutte le tabelle potresti aver bisogno di un "approccio".

    
risposta data 29.09.2011 - 19:13
fonte
14

Se il requisito è avere più reparti per utente, questo design ha senso. L'unica lamentela è che UserDepartmentTable ha una chiave surrogata UserDepartmentID che non è necessaria (basta rendere UserId e DepartmentId una chiave primaria composta).

Se un utente appartiene sempre a un singolo dipartimento, la progettazione ha senso (anche se una tabella di ricerca reparto sarebbe comunque una buona cosa).

    
risposta data 29.09.2011 - 18:50
fonte
5

Alcuni requisiti non sono chiari nella tua domanda. La risposta corretta dipende da ciò che desidera il cliente - Se fossi in te, chiederei al cliente:

0-Qual è la differenza tra un utente e un dipendente?

1-Assumendo un dipendente = utente, che succede se un dipendente cambia reparto?

2-Un gruppo di dipendenti può effettuare 1 richiesta?

3-Un dipendente può appartenere a più di un dipartimento? Che dire del CEO

4-C'è un sottoinsieme di dipendenti che possono fare richieste?

5-Cosa succede alla richiesta quando un record dipendente viene cancellato (se mai)?

6-Potresti cancellare una richiesta? Cosa succede quando la richiesta viene eliminata (assicurati di non eliminare il record del dipendente da RI)

7-Il dipendente può fare la "stessa" richiesta più di una volta (definire lo "stesso")

8-Come gestire le richieste per i dipendenti quando lasciano l'azienda (annullare le loro richieste o eliminare le richieste?)

Potrebbero esserci altre domande, ma il mio punto è che la soluzione dipende da requisiti esatti e ambito del progetto. Una volta stabilito lo schema può essere derivato direttamente. Di conseguenza entrambe le soluzioni presentate potrebbero essere corrette.

    
risposta data 30.09.2011 - 01:36
fonte
1

Vorrei aggiungere un modulo in forma di coppia che parla esplicitamente di alcuni dei potenziali vantaggi dell'utilizzo di una tabella di join nel modo in cui lo ha fatto il consulente altamente pagato.

  • Correttamente indicizzato (ad esempio, se UserDepartmentTable indicizza le due chiavi esterne), c'è solo una piccola perdita di prestazioni di una tabella di join come questa a causa delle chiavi esterne che non sono univoche. Se le chiavi esterne sono garantite come uniche, secondo la piccola teoria del database che conosco, cercare UserDepartmentTable.Department non è "più difficile" di cercare qualsiasi altra colonna nella tabella User .
  • La tabella di join ti offre una maggiore flessibilità per impostare altre informazioni sull'associazione tra l'utente e il dipartimento (ad es. timestamp alla creazione).
  • La tabella di join consente di "eseguire" abbastanza facilmente l'associazione (ad esempio, quando un utente cambia reparto, attiva qualche indicatore booleano dell'indice come UserDepartmentTable.Active su false e crea una nuova associazione attiva). È anche possibile avere versioni di associazioni di reparto con il modello a due tabelle (solo utente e reparto), ma è più difficile e richiede l'aggiunta di almeno un'altra colonna o l'esecuzione di acrobazie di database per evitare la duplicazione delle chiavi primarie.
  • Ti consente di assegnare facilmente le associazioni uno a molti o molti a molti o molti a molti.

Detto questo, ci sono diversi motivi per NON fare ciò che ha fatto il tuo consulente altamente pagato.

  • Tutti i benefici di cui sopra sono tutti anticipatori di possibili bisogni futuri, complicando eccessivamente le cose per il presente. Non è conforme allo YAGNI. In seguito, è di difficile difficoltà scrivere una migrazione che passi dal modello a due tabelle a un modello di tabella di join. Puoi farlo quando emergono le esigenze aziendali. Per farlo prima può essere fonte di confusione.
  • Confonde gli altri sviluppatori. Mentre, sì, direi che l'aspettativa per uno sviluppatore web della tua statura (dove stai rivedendo le decisioni dei consulenti) sarebbe capire e riconoscere una tabella di join, è ancora più complicata del necessario e considerando la mancanza di necessità aziendali, provoca confusione.
risposta data 30.09.2011 - 16:04
fonte
0

Senza la struttura completa delle informazioni necessarie non posso dire che sia terribile o no. Ma almeno il pezzo mostrato non è di design "WTF". Sembra solo una terza forma normale di struttura dei dati (beh, teoricamente abbiamo anche 4-rd e 5-esimo)

Alcuni colloqui possono avere luogo per UserDepartmentTable tra due scuole di chiavi "naturali" e "artificiali" nel pezzo mostrato. Niente di più, come posso vedere

La normalizzazione è la regola del buon progettista / progettista di DB per molte ragioni, * de * le normalizzazioni sono usate a volte nel mezzo di sviluppi per lo speed-win per lo più

    
risposta data 30.09.2011 - 15:12
fonte

Leggi altre domande sui tag