Risposte alle tue domande individuali
Se voglio aggiungere una colonna Club
che descriva il proprietario, che sarà anche un membro, qual è l'approccio migliore senza avere lo stesso membro elencato due volte?
Se —come indicato nelle vostre specifiche a Person can be a Member of only one Club
— e siete interessati a memorizzare questo dato semplicemente come vero o falso , un'opzione è aggiungere una BIT(1)
o una colonna BOOLEAN
( TINYINT
) alla Person
tabella e potreste voler chiamare questa colonna IsClubOwner
. In questo modo, è possibile registrare il fatto che una determinata persona è il proprietario di un club solo una volta. A parte questo, questo metodo offre anche la possibilità di trattenere diverse persone come proprietari dello stesso club . Puoi vedere una rappresentazione a livello logico di questo approccio nella Figura 1 .
Tuttavia, stai cercando l'approccio migliore e, secondo la mia esperienza, tale approccio comporta lo sviluppo di una struttura molto più espandibile e versatile. A questo proposito, segui la progressione di un esercizio di modellizzazione per questi e altri punti di seguito, nelle sezioni intitolata "Copertura delle specifiche rimanenti", "Persona come membro di più club" e "Membro e proprietario come tipi di entità separati".
Dovrei mettere tutte le mie tabelle sull'incremento automatico di una id
o sarebbe una cattiva idea? (benifits / svantaggi?)
Se dovete affrontare un esplicito requisito che indica la definizione di una tabella con una colonna di tali caratteristiche, e tale colonna ha un significato contestuale valida o serve uno scopo particolare come essere un surrogato per una vasta PRIMARY KEY naturale (PK), allora sì, dovresti procedere in questo modo.
Altrimenti, se non hai detto requisito, ritengo che sarebbe inutile poiché devi archiviare e gestire una colonna aggiuntiva senza significato e (forse?) Anche un INDICE aggiuntivo nel tuo database.
Come al solito, è necessario analizzare ciascun caso insieme alle sue ripercussioni generali per decidere come procedere.
Se aggiungo chiavi esterne nella scheda Chiavi esterne, queste corrisponderanno automaticamente alla tabella corretta o devo aggiungere anche queste alle colonne?
A questo proposito, il mio consiglio per te è quello di creare manualmente la struttura del tuo database, di codificare le tue DDL
dichiarazioni fino a quando non hai una solida conoscenza dell'argomento. Se lo fai, sarà più facile per te capire i processi che gli strumenti grafici stanno eseguendo "sotto il cofano".
Per me, ad esempio, creando un'affermazione come la seguente:
CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)
È molto più istruttivo dell'utilizzo degli strumenti della GUI per eseguire questo tipo di attività, soprattutto ora che stai costruendo i tuoi primi progetti.
E la mia domanda probabilmente più rumorosa di tutte ... Metto le chiavi esterne di phone_number
e email
nella loro rispettiva tabella che si collega a una person_id
o dovrei mettere phone_number
e email
ids
nella tabella persona?
Personalmente, penso che questa e tutte le altre domande siano completamente valide e ben contestualizzate .
Tornando agli aspetti tecnici che ci riguardano, questa indagine precisa offre una buona opportunità per rivedere le due seguenti affermazioni:
A Person can be reached through zero-one-or-many PhoneNumbers
A PhoneNumber can be used to reach one-to-many People
Quindi, si può concludere che esiste una relazione molti-a-molti tra Person
e PhoneNumber
, quindi, suggerisco la creazione di una tabella associativa denominata PersonPhoneNumber
per rappresentare detta relazione nel database. Il PK di questa tabella dovrebbe essere composto da due colonne diverse: PersonId
(un KEY ESTERO [FK] che punta a Person.PersonId
) e PhoneNumber
(un FK che fa riferimento a PhoneNumber.Number
). Per una descrizione del livello logico di tutto quanto sopra, vedere la Figura 1 .
D'altra parte, esaminiamo le due proposizioni che seguono:
A Person can be contacted via zero-one-or-many EmailAddresses
An EmailAddress can be used to contact exactly one Person
Quindi, sì, è necessario impostare un riferimento alla FK Person
dal EmailAddress
tavolo, e questo tavolo dovrebbe avere una PK composito troppo, che sarebbe composta da colonne PersonId
e Address
. In questo modo, puoi assicurarti che la stessa combinazione di EmailAddress.PersonId
e EmailAddress.Address
possa essere inserita una sola volta.
Se desideri anche assicurarti che un dato EmailAddres.Address
possa essere archiviato in una sola riga, devi solo stabilire un VINCOLO UNICO per questa colonna.
Modelli di dati logici proposti
Per esporre più chiaramente i miei suggerimenti, ho incluso quattro distinti modelli logici IDEF1X [1] che sono mostrati in Figura 1 , Figura 2 , Figura 3 e Figura 4 . Fornirò una spiegazione delle funzionalità più rilevanti visualizzate in ognuna di esse nelle sezioni corrispondenti. Puoi anche scaricare da Dropbox un PDF che integra in un singolo modello la maggior parte degli elementi in discussione.
Coprendo le tue restanti specifiche
Relativi a persone e indirizzi
Esaminiamo le due seguenti affermazioni (leggermente riformulate) che sono rilevanti per le persone e gli indirizzi :
A Person can only have one Address
An Address can belong to different People (couples or siblings)
Quindi, per far fronte a queste restrizioni, puoi scegliere di implementare un modello di dati simile a quello che puoi vedere nella Figura 1 .
Tenendo conto del modello indicato, è necessario seguire i passaggi seguenti:
Crea una tabella chiamata PersonAddress
fissando una relazione tra Person
e Address
. Imposta le colonne PersonId
e AddressId
come PK composto di questa tabella.
Configurare un VINCOLO UNICO per la PersonAddress.PersonId
colonna per garantire che un valore specifico possa essere inserito al massimo in una riga di detta tabella. A livello logico, questa circostanza implica che PersonAddress.PersonId
è diventato un ALTERNATE KEY [2] .
Se il valore di AddressId
in un determinato PersonAddress
tentativo di inserimento non è già stato memorizzato, quindi lasciare che l'inserimento continui, altrimenti, quando tale valore esiste già in una riga, è necessario verificare che (a) PersonId
chi ha registrato che AddressId
sia anche registrato come Marriage.WifeId
se PersonId
è un maschio (dato derivato tramite Person.GenreCode
) o (b) che PersonId
è il Marriage.HusbandId
quando PersonId
è una femmina (derivata anche in virtù di Person.GenreCode
). Se una di queste condizioni è soddisfatta nella situazione appropriata, allora si dovrebbe lasciare andare INSERT.
Se le condizioni di cui sopra non sono state soddisfatte, c'è ancora la possibilità che un PersonAddress
inserimento tenti di avere successo. Devi verificare che il PersonId
valore coinvolto in detto inserimento provi a condividerne almeno uno Progeny.ParentId
con quello PersonId
che ha già registrato il file PersonAddress.AddressId
. Se questa condizione è soddisfatta, significa che sono archiviati come Siblings
nel database, quindi INSERT deve avere esito positivo.
Come in qualsiasi implementazione di database relazionale, dovresti prendere seriamente in considerazione di eseguire le tue DML
operazioni all'interno di Transazioni ACID in modo da poter proteggere l' integrità e la coerenza dei dati con cui stai lavorando.
Partecipare ai requisiti che hai aggiunto nei commenti: indirizzi e numeri di telefono che servono sia i club che le persone
A condizione che si desideri dare la possibilità a indirizzi e numeri di telefono di servire sia persone che club , è possibile utilizzare una relazione supertipo-sottotipo . Ecco una risposta in cui do un trattamento più dettagliato a questo tipo di strutture, nel caso tu sia interessato.
Nel presente scenario, è possibile definire Person
e Club
come sottotipi di una nuova entità denominata Party
, un termine comunemente usato negli ambienti legali per indicare (a) una persona o (b) un gruppo di persone (come indicato nel senso n. 6 ). Con questo metodo, le relazioni tra Addresses
(o PhoneNumbers
) e People
e Clubs
sarebbero definite attraverso Party
il supertipo. Vedere la Figura 2 per una rappresentazione di questo suggerimento.
Parte e indirizzo
Quindi possiamo leggere in questo nuovo modello che:
A Party keeps zero-one-or-many Addresses
An Address is kept by one-to-many Parties
Pertanto, esiste una relazione molti-a-molti che coinvolge Party
e Address
che si esprime attraverso l' PartyAddress
entità.
Numero di parte e telefono
Inoltre, possiamo interpretare che:
A Party is reached through zero-one-or-many PhoneNumbers
A PhoneNumber is used by one-to-many Parties
Ecco perché ho aggiunto l' PartyPhoneNumber
entità che descrive l'associazione molti-a-molti che ha effetto tra i tipi di entità Party
e PhoneNumber
.
Partito e club o persona
Quindi, si può anche leggere che:
A Party is either a Club or a Person
Quindi, Party
fornisce un collegamento da uno Clubs
o People
a Addresses
(o PhoneNumbers
).
Persona come membro di più club
Come menziona @aldwinaldwin nella sua risposta, se si desidera fornire la funzionalità affinché una persona sia membro di più club , è possibile includere un tavolo chiamato ClubMember
che fungerebbe da un'altra relazione molti-a-molti, questa volta, naturalmente , interconnessione Person
e Club
.
Aggiungerò a quanto sopra che questa tabella può anche essere utile nell'obiettivo di memorizzare qualsiasi persona concreta come proprietario di più club , mediante l'inclusione della IsClubOwner
colonna booleana già menzionata . In effetti, si può dire che questa nuova tabella è la rappresentazione di un tipo di entità integrale a sé stante.
Come dimostrato nella Figura 3 , tale tabella richiede un PK composto composto da colonne ClubId
e MemberId
(un nome di ruolo [3] assegnato a PersonId
), e queste colonne devono essere definite anche come FK che puntano, corrispondentemente, a Club
e Person
.
Una struttura più adattabile
Utilizzando questa impostazione è anche possibile rispettare la regola iniziale che stabilisce che a Person can be a member of only one Club
, ma è sufficiente aggiungere un VINCOLO UNICO alla MemberId
colonna, in modo che un determinato valore possa essere inserito in non più di un'occasione. Quindi, come puoi notare, questa struttura è molto più adattabile di quella mostrata in Figura 1 , poiché rilasciando il Vincolo UNICO (o INDICE) apriresti la funzionalità di cui sopra per consentire a una persona di diventare un membro di diversi club del contemporaneamente.
Membro e proprietario come tipi di entità separati
Come sapete, l'archiviazione di diversi fatti sul ruolo svolto da una persona come proprietario di un club - a parte la sua semplice esistenza in un attributo vero o falso - può essere molto vantaggioso. Ad esempio, potresti voler mantenere la data effettiva in cui una persona definita è diventata il proprietario di un club , quindi puoi gestire questa situazione introducendo un tipo di entità separato chiamato ClubOwner
, come presentato nella Figura 4 .
Una volta costruito un tavolo basato su questo nuovo tipo di entità, è possibile aggiungere le colonne di adattamento che rappresentano le caratteristiche che entrano in gioco esclusivamente quando a Person
è il Owner
di a Club
. Come illustrato, questa tabella conterrebbe un PK composto dalle colonne FK che fanno riferimento Person.PersonId
e Club.ClubId
, in questo modo, qualsiasi combinazione di ClubOwner.OwnerId
(o ClubOwner.PersonId
, se preferisci) e ClubOwner.ClubId
può essere inserita in una sola opportunità.
Naturalmente, con questa configurazione è ancora possibile derivare in forma booleana se a Person
è il Owner
particolare di un particolare Club
con l'aiuto di una query che restituisce un valore scalare che può essere valutato come vero o falso .
Appunti
1. Integration Definition for Information Modeling ( IDEF1X ) è una tecnica di modellazione dei dati altamente raccomandabile che è stata definita come standard nel dicembre 1993 dal National Institute of Standards and Technology ( NIST ) degli Stati Uniti . Si è solidamente basata su (a) alcuni dei documenti teorici scritti da creatore del modello relazionale , vale a dire, il Dr. EF Codd ; su (b) la teoria Entità-Relazione , sviluppata dal Dott. PP Chen ; e anche su (c) la tecnica di progettazione del database logico , creata da Robert G. Brown . Vale la pena notare che IDEF1X eraformalizzato mediante la logica del primo ordine .
2. Una chiave alternativa è un attributo (o una combinazione di attributi) che contiene valori che identificano in modo univoco un'occorrenza di entità ma non è stato scelto come PK del tipo di entità pertinente; ogni tipo di entità può avere zero, uno o più TASTI ALTERNATIVI. In un modello IDEF1X, sono indicati come "AK" più il rispettivo numero, ad esempio AK1, AK2, ecc. Di solito sono implementati in una struttura DDL SQL tramite un VINCOLO UNICO (o un INDICE UNICO ).
3. I nomi dei ruoli sono denotazioni (o alias) assegnati agli attributi FK per esprimere il significato che ricoprono nell'ambito delle rispettive entità. Il loro utilizzo è raccomandato dal 1970 dal dott. Codd nel suo documento fondamentale intitolato "Un modello relazionale di dati per grandi banche dati condivise" . Da parte sua, IDEF1X - mantenere la fedeltà riguardo alle pratiche relazionali - sostiene anche la denominazione dei ruoli.
clubId
di telefono e lascio il club o la persona impostati su null?