Le tabelle del database dovrebbero essere separate per preoccupazione?

0

La mia domanda è relativa a quando una tabella di database deve essere suddivisa in più tabelle con relazioni? Tuttavia, ho una relazione uno a uno più chiara rispetto a quella in questione.

Se stavo progettando la seguente tabella da zero dovrebbe essere in una o due tabelle?

ORDERS
id
date
total_amount
is_paid
paid_date
paid_amount
has_discrepancy
discrepancy_reason

Un ordine non viene mai pagato al momento della creazione. Può o non può essere pagato in seguito. Mi è stato detto che dal momento che ha una corrispondenza uno-a-uno dovrebbe sempre essere in un unico tavolo. Se is_paid è FALSE , i campi rimanenti sono sempre NULL . Tuttavia, il seguente disegno ha più senso per me:

ORDERS
id
date
total_amount

PAYMENTS
id
order_id
paid_date
paid_amount
has_discrepancy
discrepancy_reason

Un altro esempio:

EMPLOYEES
id
first_name
last_name
date_of_birth
is_married
spouse_first_name
spouse_last_name
spouse_date_of_birth

Per me sembra che sia lo stesso del primo esempio in cui se is_married è FALSE i campi rimanenti sono NULL e penso che dovrebbe essere scomposto in questo modo:

EMPLOYEES
id
first_name
last_name
date_of_birth

SPOUSES
id
married_to_employee_id
spouse_first_name
spouse_last_name
spouse_date_of_birth

Il primo progetto in ciascun caso presuppone che una relazione uno-a-uno sia naturale. Tuttavia, i piani di pagamento con pagamenti multipli non sono inauditi, né i matrimoni poligami. Sto solo pensando troppo a questo? Dovrei semplicemente svolgere il compito a portata di mano o dovrei pensare se i dati appartengano veramente o meno alla stessa tabella?

Mi è stato detto che non si memorizzerebbe il nome di una persona in una tabella separata solo per i nomi e che lo stesso principio si applica qui, ma la differenza è che non si progetterebbe la tabella in questo modo:

EMPLOYEES
id
has_first_name
first_name
has_last_name
last_name
has_date_of_birth
date_of_birth

Se hai una colonna che ti dice solo se altre colonne sono popolate o meno, non è meglio memorizzare quei valori in una tabella separata? O è meglio semplificare il codice avendo a che fare solo con una tabella?

    
posta CJ Dennis 10.07.2016 - 04:11
fonte

4 risposte

2

Dipende è l'unica vera risposta qui. Il motivo per cui fai questa domanda e sei in dubbio è dovuto al fatto che non sei chiaro sulle specifiche da costruire.

Domande di esempio che dovresti chiedere sull'esempio di ordini.

Richiesta iniziale del proprietario client / prodotto:

"Vogliamo vedere se gli ordini vengono pagati nella schermata degli ordini."

Le tue domande:

Cool, certo che possiamo farlo. Gli ordini vengono pagati tutti in una volta?

Cliente: Sì perché utilizziamo PayPal che non consente di modificare l'importo in modo che sia pagato o non pagato.

Cliente: No, a volte consegniamo in spedizioni separate e pagheremo solo l'importo consegnato.

O Cliente: No, dipende dal nostro sistema di fatturazione qui.

Tu: Ah così in realtà pagano la fattura, non l'ordine?

Etcetera eccetera. Non è un problema tecnico, è un problema di requisiti. E non è possibile risolvere i requisiti non chiari con soluzioni tecniche. (Potresti conoscere il diagramma dell'oscillazione dei requisiti: link ).

    
risposta data 11.07.2016 - 10:22
fonte
1

Non stai pensando troppo - le tue domande sono molto rilevanti per il design. Ma non sono domande tecniche, sono domande sui requisiti. Il tuo sistema dovrebbe supportare piani di pagamento o matrimoni poligami? Queste non sono domande tecniche, queste sono decisioni aziendali.

Per quanto riguarda i coniugi, anche se è ovvio che devi supportare i dipendenti non sposati, quindi devi spouse_first_name ecc. in una tabella separata con una chiave esterna alla tabella Employee . (Puoi prevenire la poligamia avendo un vincolo univoco sulla chiave esterna, se lo desideri.) Ovviamente questo potrebbe avere problemi se due impiegati si sono sposati l'uno con l'altro - ancora una volta dipende dai requisiti.

Quando hai deciso un modello di business, puoi progettare il database. Se alcune entità hanno una relazione uno-a-uno, dovrebbero trovarsi in un'unica tabella e, se hanno uno-a-molti, dovrebbero trovarsi in più tabelle. (Uno a zero o uno come per gli sposi è un caso speciale di uno a molti.)

Il design del database non dovrebbe seguire la separazione delle preoccupazioni nel solito senso. Puoi avere dipendenti della misura della scarpa e dell'animale preferito nella stessa tabella, anche se non sono correlati, purché il cliente ne abbia esattamente uno ciascuno.

Come per has_first_name , has_spouse ecc .: non hai bisogno di campi come questi. Se un singolo campo è facoltativo, utilizzare NULL per indicare il valore mancante. Un flag non fornisce alcuna informazione aggiuntiva e corri il rischio di dati incoerenti (ad es. Cosa succede se c'è un nome ma false in has_first_name ?).

Se si tratta di più valori opzionali come gruppo (come ' spouse_first_name ', ' spouse_last_name '), allora dovrebbe essere un'entità separata (il Spouse -table), quindi di nuovo una bandiera separata è non necessario.

    
risposta data 11.07.2016 - 17:24
fonte
1

In parole povere:

L'intero punto dei database relazionali è la normalizzazione.

Normalizzazione significa separare tabelle in tabelle diverse per evitare anomalie udpate e velocizzare le ricerche, ridurre la ridondanza ecc.

Quindi la tua domanda è veramente "se un database deve essere normalizzato?" e la risposta è "ovviamente" . Ovviamente ci sarebbero eccezioni in una tabella per tavolo in cui puoi decidere di denormalizzare per fini di prestazioni.

La normalizzazione impone che una colonna non chiave descriva la chiave, l'intera chiave e nient'altro che la chiave. Quindi dovresti evitare cose come avere il nome del negozio in cui è stato acquistato un prodotto nella tabella del prodotto.

Nel caso delle tabelle fornite come esempi, le inserirò in una tabella separata. Non esiste una relazione uno a uno in un database relazionale, ma è possibile simularne una aggiungendo il PK corretto nella tabella figlio in modo che non sia possibile inserire un secondo coniuge per lo stesso dipendente, o un secondo pagamento a un ordine se questa è la regola aziendale. Ma una soluzione più ragionevole sarebbe quella di aggiungere date al tavolo del coniuge in modo da memorizzare una cronologia degli sposi, ma potresti sempre trovare quella corrente e avere più pagamenti per un ordine.

D'altra parte, hasSpouse è un campo calcolato che indica se le colonne correlate al coniuge sono o meno popolate o meno. I campi calcolati non sono conformi ai moduli normali e devono essere utilizzati solo nelle tabelle di riepilogo (che non rispettano le regole di normalizzazione poiché non sono transazionali). Ma in questo caso è peggio perché non è una somma totale di altre colonne ma un indicatore che potrebbe essere sostituito semplicemente chiedendo se una colonna è nullo o meno.

    
risposta data 11.07.2016 - 17:39
fonte
0

Non sono sicuro di quale scopo richieda i campi has_xxx. È comune utilizzare colonne nullable in cui la colonna potrebbe non avere un valore. Dovrai farlo comunque per le colonne corrispondenti ai campi has_xxx. Se il valore non è NULL, has_xxx dovrebbe essere true, e se il valore è NULL, allora has_xxs dovrebbe essere falso. Questo rende le colonne has_xxx derivabili, quindi dovrebbero essere normalizzate.

Alcune interfacce che restituiscono valori primitivi potrebbero avere problemi con il valore NULL. Possono restituire 0 per valori numerici e una stringa vuota per stringa e tipi di valori correlati. Possono avere un valore IS_NULL correlato che può essere interrogato o impostato in DML. Tuttavia, questi valori non richiedono colonne corrispondenti nel database.

Alcuni puristi di modellazione non consentirebbero valori NULL nel database, ma ciò richiederebbe una tabella separata per ogni insieme di valori nullable. Questo è utile concettualmente. Tuttavia, devo ancora lavorare su un sistema in cui ho visto l'implementazione fisica (database) normalizzata in tale misura.

Nel modello, la data di pagamento e l'importo pagato dovrebbero avere vincoli di integrità che richiedono che siano entrambi NULL o NULL. È comune gestire i pagamenti in una tabella separata. Questo avrebbe una tabella di join per gli ordini pagati da quel pagamento. La tabella di join potrebbe avere una colonna di importo che indica la quantità del totale dell'ordine pagato da quel pagamento.

Il tuo esempio di dipendente è vicino a ciò che ho visto implementato. Invece di una tabella dei coniugi, potresti volere una tabella dei dipendenti. La tabella delle persone a carico potrebbe includere presenze, bambini, genitori e, eventualmente, altri tipi di dipendenti. In alternativa. entrambi i dati personali per dipendenti e dipendenti potrebbero trovarsi in una singola tabella di persone con una tabella di join circolare. I dati specifici dei dipendenti rimarrebbero in una tabella dei dipendenti a cui la tabella delle persone avrebbe una relazione facoltativa da 1 a 1 (o da 1 a 0,1).

    
risposta data 11.07.2016 - 03:12
fonte

Leggi altre domande sui tag