Secondo la mia interpretazione della tua descrizione del contesto aziendale di interesse, hai a che fare con una struttura di sottotipo di sottotipo 1 in cui (a) attore , regista e scrittore sono sottotipi di entità di (b) persona , il loro sottotipo di entità e (c) detti sottotipi non si escludono a vicenda.
In questo modo, se sei interessato a costruire un database relazionale che rispecchi accuratamente uno scenario del genere, e quindi ti aspetti che funzioni come tale, i tuoi chiarimenti sui commenti che seguono sono abbastanza significativi rispetto ai punti precedenti, perché hanno implicazioni in entrambi (1) i livelli concettuali e (2) logici di rappresentazione del database in questione:
[…] Tabelle aggiuntive per ciascuno dei rispettivi tipi di utenti che hanno ciascuno il proprio set univoco di colonne.
[…] Ci sono solo quattro tipi di utenti che sono rilevanti. Esiste una possibilità esterna che questo numero possa aumentare, ma la probabilità è bassa - e in tal caso sarebbe un numero molto piccolo.
Descriverò tutti questi aspetti e molti altri fattori critici nelle sezioni seguenti.
Regole di business
Al fine di definire innanzitutto lo schema concettuale corrispondente, che può essere utilizzato come riferimento successivo in modo da poterlo adattare per assicurarsi che soddisfi i requisiti informativi esatti , ho formulato alcune regole di business di particolare importanza:
- Una persona può svolgere ruoli da uno a due o tre (cioè da tutti a tutti) 2 . In altre parole, una persona può essere
- un attore e
- un direttore e
- uno scrittore .
- Una persona può accedere tramite UserProfile zero o uno .
- Un attore fornisce uno o due o tre URL 3 .
- Un attore è raggruppato per un'etnia .
- Un Etnia gruppi zero-uno-o-molti attori .
- Uno scrittore si basa in una posizione .
- Una posizione è la base di zero-uno-o più scrittori .
Diagramma IDEF1X dell'esposizione
Quindi, ho creato il diagramma IDEF1X 4 mostrato nella Figura 1 , che raggruppa tutte le formulazioni sopra insieme ad altre regole che sembrano pertinenti:
Come dimostrato, il supertipo Person (i) ha una propria casella, (ii) possiede le proprietà o gli attributi che si applicano a tutti i sottotipi e (iii) presenta linee che lo collegano alle caselle di ogni sottotipo.
A sua volta, ogni sottotipo (a) appare nella sua casella dedicata e (b) detiene esclusivamente le proprietà applicabili. Il PRIMARY KEY del supertipo, PersonId , migra 5 nei sottotipi con i nomi dei ruoli 6 ActorId , DirectorId e WriterId rispettivamente.
Inoltre, ho evitato di associare Person con il tipo di entità UserProfile , che consente di separare tutte le loro implicazioni contestuali, associazioni o relazioni, ecc. La proprietà PersonId è migrata a UserProfile con il nome ruolo UserId .
Lo affermi nel corpo della domanda
E tutti gli attori dovranno includere almeno un URL per uno dei loro altri profili di attori online; attualmente ci sono tre che possono includere, ma questo numero può aumentare.
... quindi l' URL è un tipo di entità a sé stante ed è direttamente associato al sottotipo Actor in conformità con questa citazione.
E, nei commenti , lo specifichi
[...] un attore avrà un colpo alla testa (foto), mentre uno scrittore non [...]
... poi, tra le altre caratteristiche, ho incluso Headshot come proprietà del tipo di entità Attore .
Per quanto riguarda i tipi di entità Etnia e Ubicazione , ovviamente possono comportare organizzazioni più complesse (ad esempio, un Attore può appartenere a uno, due o più diversi gruppi etnici in proporzioni distinte e uno Scrittore può essere basato su un luogo che richiede la registrazione paese, regione amministrativa, contea, ecc.) ma sembra che le esigenze del tuo contesto aziendale siano coperte con successo con le strutture qui modellate.
Naturalmente, puoi apportare tutte le regolazioni necessarie.
Progettazione logica illustrativa SQL-DDL
Di conseguenza, sulla base del diagramma IDEF1X mostrato e descritto sopra, ho scritto il layout logico DDL che viene mostrato come segue (ho fornito note come commenti che spiegano alcune delle caratteristiche che reputo particolarmente importanti rispetto a tabelle, colonne e vincoli dichiarato):
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- Also, you should make accurate tests to define the
-- most convenient INDEX strategies based on the exact
-- data manipulation tendencies of your business needs.
-- As one would expect, you are free to utilize
-- your preferred (or required) naming conventions.
CREATE TABLE Person ( -- Represents the supertype.
PersonId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
BirthDate DATE NOT NULL,
GenderCode CHAR(3) NOT NULL,
TwitterProfile CHAR(30) NOT NULL,
PhoneNumber CHAR(30) NOT NULL,
EmailAddress CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Person_PK PRIMARY KEY (PersonId),
CONSTRAINT Person_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
FirstName,
LastName,
GenderCode,
BirthDate
),
CONSTRAINT Person_AK2 UNIQUE (TwitterProfile), -- ALTERNATE KEY.
CONSTRAINT Person_AK3 UNIQUE (EmailAddress) -- ALTERNATE KEY.
);
CREATE TABLE Ethnicity ( -- Its rows will serve a “look-up” purpose.
EthnicityId INT NOT NULL,
Name CHAR(30) NOT NULL,
Description CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Ethnicity_PK PRIMARY KEY (EthnicityId),
CONSTRAINT Ethnicity_AK UNIQUE (Description)
);
CREATE TABLE Actor ( -- Stands for one of the subtypes.
ActorId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Headshot CHAR(30) NOT NULL, -- May, e.g., contain a URL indicating the path where the photo file is actually stored.
EthnicityId INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Actor_PK PRIMARY KEY (ActorId),
CONSTRAINT ActorToPerson_PK FOREIGN KEY (ActorId)
REFERENCES Person (PersonId),
CONSTRAINT ActorToEthnicity_PK FOREIGN KEY (EthnicityId)
REFERENCES Ethnicity (EthnicityId)
);
CREATE TABLE Director ( -- Denotes one of the subtypes
DirectorId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Bio CHAR(120) NOT NULL,
Etcetera CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Director_PK PRIMARY KEY (DirectorId),
CONSTRAINT DirectorToPerson_PK FOREIGN KEY (DirectorId)
REFERENCES Person (PersonId)
);
CREATE TABLE Country (
CountryCode CHAR(2) NOT NULL,
Name CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Country_PK PRIMARY KEY (CountryCode),
CONSTRAINT Country_AK UNIQUE (Name)
);
CREATE TABLE Location ( -- Its rows will serve a “look-up” purpose.
CountryCode CHAR(2) NOT NULL,
LocationCode CHAR(3) NOT NULL,
Name CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Location_PK PRIMARY KEY (CountryCode, LocationCode),
CONSTRAINT Location_AK UNIQUE (CountryCode, Name)
);
CREATE TABLE Writer ( -- Represents one of the subtypes.
WriterId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
CountryCode CHAR(2) NOT NULL,
LocationCode CHAR(3) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Writer_PK PRIMARY KEY (WriterId),
CONSTRAINT WriterToPerson_PK FOREIGN KEY (WriterId)
REFERENCES Person (PersonId),
CONSTRAINT WriterToLocation_PK FOREIGN KEY (CountryCode, LocationCode)
REFERENCES Location (CountryCode, LocationCode)
);
CREATE TABLE UserProfile (
UserId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
UserName CHAR(30) NOT NULL,
Etcetera CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
CONSTRAINT UserProfile_AK UNIQUE (UserName), -- ALTERNATE KEY.
CONSTRAINT UserProfileToPerson_PK FOREIGN KEY (UserId)
REFERENCES Person (PersonId)
);
CREATE TABLE URL (
ActorId INT NOT NULL,
Address CHAR(90) NOT NULL,
Etcetera CHAR(30) NOT NULL,
AddedDateTime DATETIME NOT NULL,
--
CONSTRAINT URL_PK PRIMARY KEY (ActorId, Address), -- Composite PRIMARY KEY.
CONSTRAINT URLtoActor_FK FOREIGN KEY (ActorId)
REFERENCES Actor (ActorId)
);
Pertanto, (1) ogni aspetto singolare del layout logico sopra riportato ha un significato molto preciso da (2) una caratteristica singolare dell'ambiente di business di interesse 7 — in accordo con lo spirito del quadro relazionale del Dr. Edgar Frank Codd -, perché:
- Ogni tabella di base rappresenta un tipo di entità individuale.
- Ogni colonna rappresenta una singola proprietà del rispettivo tipo di entità.
- Un tipo di dati specifico è fissato per ogni colonna al fine di garantire che tutti i valori in esso contenuti appartengano a un insieme particolare e delimitato correttamente a, sia INT, DATETIME, CHAR, ecc. (E speriamo che MySQL integrerà finalmente DOMAIN supporto nella versione futura).
- Più vincoli sono configurati (in modo dichiarativo) al fine di garantire che le asserzioni sotto forma di righe conservate in tutte le tabelle siano conformi alle regole di business determinate a livello concettuale.
Ogni riga ha lo scopo di trasmettere una semantica ben definita, ad esempio una Person
riga viene letta
La persona identificata da PersonId r
viene chiamata da FirstName s
e LastName t
, è nata il giorno della nascita u
, ha il GenderCode v
, i tweet sul profilo Twitter w
, è raggiunta tramite PhoneNumber x
, è contattata tramite EmailAddress y
ed è stata registrata su CreatedDateTimez
.
Avere un layout come questo è decisamente favorevole, in quanto è possibile ricavare nuove tabelle (ad esempio, operazioni SELECT che raccolgono colonne DA più tabelle con l'aiuto della clausola JOIN) che - in successione - hanno anche un significato molto preciso (vedere la sezione intitolato "Visualizzazioni" di seguito).
Va detto che, con questa configurazione, (i) una riga che rappresenta un'istanza di sottotipo è identificata da (ii) lo stesso valore PRIMARY KEY che distingue la riga che indica l'occorrenza del supertipo complementare. Pertanto, è più che opportuno annotarlo
- (a) collegare una colonna aggiuntiva per contenere surrogati generati dal sistema e assegnati al sistema da 8 a (b) le tabelle che rappresentano i sottotipi è (c) del tutto superflua .
Con questo progetto logico, se i nuovi sottotipi sono definiti rilevanti nel contesto aziendale, è necessario dichiarare una nuova tabella di base, ma ciò accade anche quando altri tipi di tipi di entità sono considerati significativi, quindi la situazione sarebbe, in infatti, ordinario.
Visualizzazioni
Per "recuperare", ad esempio, tutte le informazioni che corrispondono a un attore , regista o scrittore , è possibile dichiarare alcune visualizzazioni (ovvero tabelle derivate o espressibili ) in modo da poter SELEZIONARE direttamente da una singola risorsa senza dover scrivere il per quanto riguarda JOINs ogni volta; ad esempio, con la VISTA dichiarata di seguito, è possibile ottenere le informazioni "complete" sull'attore :
--
CREATE VIEW FullActor AS
SELECT P.FirstName,
P.Lastname,
P.BirthDate,
P.GenderCode,
P.TwitterProfile,
P.PhoneNumber,
P.EmailAddress,
A.Headshot,
E.Name AS Ethnicity
FROM Person P
JOIN Actor A
ON A.ActorId = P.PersonId
JOIN Ethnicity E
ON E.EthnicityId = A.EthnicityId;
--
Naturalmente, è possibile seguire un approccio simile al fine di recuperare le informazioni "complete" su Director e Writer :
--
CREATE VIEW FullDirector AS
SELECT P.FirstName,
P.Lastname,
P.BirthDate,
P.GenderCode,
P.TwitterProfile,
P.PhoneNumber,
P.EmailAddress,
D.Bio,
D.Etcetera
FROM Person P
JOIN Director D
ON D.DirectorId = P.PersonId;
--
CREATE VIEW FullWriter AS
SELECT P.FirstName,
P.Lastname,
P.BirthDate,
P.GenderCode,
P.TwitterProfile,
P.PhoneNumber,
P.EmailAddress,
L.Name AS Location,
C.Name AS Country
FROM Person P
JOIN Writer W
ON W.WriterId = P.PersonId
JOIN Country C
ON C.CountryCode = W.CountryCode
JOIN Location L
ON L.LocationCode = W.LocationCode;
--
Ho pubblicato tutte le dichiarazioni DDL e le viste DML qui discusse in questo SQL Fiddle in esecuzione su MySQL 5.6 in modo da poterle vedere e testare "in azione".
Note finali
1 In alcune tecniche di modellazione concettuale, le associazioni supertipo-sottotipo sono definite relazioni superclasse-sottoclasse .
2 Anche se dici che in realtà esistono più ruoli che una persona può svolgere, ma i tre che hai rivelato sono abbastanza buoni da discutere dello scenario esponendo diverse importanti ramificazioni .
3 Ma, come hai notato, in futuro un attore potrebbe eventualmente fornire da uno a molti URL .
4 Integration Definition for Information Modeling ( IDEF1X ) è una tecnica di modellazione altamente raccomandabile che è stata stabilita come standard nel dicembre 1993 dal National Institute of Standards and Technology (NIST) degli Stati Uniti . Si basa su (a) le prime opere teoriche create dall'unico creatore del modello relazionale di dati, ovvero il Dr. EF Codd; su (b) il punto di vista entità-relazione , sviluppato dal Dr. PP Chen ; e anche su (c) la tecnica di progettazione del database logico, creata da Robert G. Brown.
5 Lo standard IDEF1X definisce la migrazione delle chiavi come "Il processo di modellizzazione del posizionamento della chiave primaria di un'entità padre o generica [cioè un supertipo] nella sua entità figlio o categoria [cioè un sottotipo] come chiave esterna".
6 In IDEF1X, un nome di ruolo è un'etichetta distintiva assegnata a un attributo FK per esprimere il significato che detiene nell'ambito del rispettivo tipo di entità.
7 Tranne, naturalmente, per le ipotetiche proprietà concettuali (e colonne logiche) Director.Etcetera e UserProfile.Etcetera , che sono semplicemente segnaposto che ho usato per esporre la possibilità di aggiungere più proprietà (e colonne) che si applicano al tipo di entità concettuale corrispondente (e tabella logica).
8 Ad esempio, aggiungendo una colonna aggiuntiva con l' attributo AUTO_INCREMENT a una tabella di un database "in esecuzione" su MySQL.