Selon mon interprétation de votre description du contexte commercial d'intérêt, vous avez affaire à une structure de supertype-sous-type 1 où (a) acteur , réalisateur et écrivain sont des sous-types d'entité de (b) personne , leur supertype d'entité, et (c) lesdits sous-types ne s'excluent pas mutuellement.
De cette façon, si vous êtes intéressé par la construction d'une base de données relationnelle qui reflète exactement un tel scénario - et que vous vous attendez donc à ce qu'il fonctionne comme tel -, les clarifications de vos commentaires suivantes sont assez importantes par rapport aux points précédents, car elles ont des implications sur à la fois (1) les niveaux conceptuels et (2) logiques de représentation de la base de données en question:
[…] Tableaux supplémentaires pour chacun des types d'utilisateurs respectifs qui ont chacun leur propre ensemble unique de colonnes.
[…] Il n'y a que quatre types d'utilisateurs qui sont pertinents. Il y a une chance extérieure que ce nombre augmente, mais la probabilité est faible - et dans ce cas, ce serait par un très petit nombre.
Je développerai tous ces aspects et plusieurs autres facteurs critiques dans les sections ci-dessous.
Règles métier
Afin de définir d'abord le schéma conceptuel correspondant - qui peut être utilisé comme référence ultérieure afin que vous puissiez l'adapter pour vous assurer qu'il répond aux exigences d'information exactes - , j'ai formulé quelques règles commerciales qui sont d'une importance particulière:
- Une personne peut remplir un ou deux ou trois (c'est-à-dire un à tous) rôles 2 . En d'autres termes, une personne peut être
- un acteur et
- un directeur et
- un écrivain .
- Une personne peut se connecter via zéro ou un profil utilisateur .
- Un acteur fournit une ou deux ou trois URL 3 .
- Un acteur est groupé par une ethnie .
- Une ethnie regroupe zéro ou un ou plusieurs acteurs .
- Un écrivain est basé dans un seul endroit .
- Un emplacement est la base de zéro un ou plusieurs écrivains .
Diagramme expositoire IDEF1X
Ensuite, j'ai créé le diagramme IDEF1X 4 illustré à la figure 1 , qui regroupe toutes les formulations ci-dessus ainsi que d'autres règles qui semblent pertinentes:
Comme démontré, le supertype Personne (i) a sa propre boîte, (ii) possède les propriétés ou les attributs qui s'appliquent à tous les sous-types, et (iii) présente des lignes qui le connectent aux boîtes de chaque sous-type.
À son tour, chaque sous-type (a) apparaît dans sa propre boîte dédiée, et (b) détient exclusivement ses propriétés applicables. La CLÉ PRIMAIRE du supertype, PersonId , migre 5 vers les sous-types avec les noms de rôle 6 ActorId , DirectorId et WriterId respectivement.
J'ai également évité de coupler Person avec le type d'entité UserProfile , ce qui permet de séparer toutes leurs implications contextuelles, associations ou relations, etc. La propriété PersonId a migré vers UserProfile avec le nom de rôle UserId .
Vous déclarez dans le corps de la question que
Et tous les acteurs devront inclure au moins une URL pour l'un de leurs autres profils d'acteurs en ligne; actuellement, ils peuvent en inclure trois, mais ce nombre peut augmenter.
… Donc l' URL est un type d'entité à part entière, et est directement associée au sous-type Acteur conformément à cette citation.
Et, dans les commentaires , vous spécifiez que
[…] Un acteur aura un headshot (photo), alors qu'un écrivain n'aura pas […]
… Puis, entre autres fonctionnalités, j'ai inclus Headshot en tant que propriété du type d'entité Acteur .
Quant aux types d'entité Ethnicité et Lieu , ils peuvent bien sûr impliquer des organisations plus complexes (par exemple, un acteur peut appartenir à un, deux ou plusieurs groupes ethniques différents dans des proportions distinctes, et un écrivain peut être basé sur un lieu qui nécessite un enregistrement pays, région administrative, comté, etc.) mais il semble que les besoins de votre contexte commercial soient couverts avec succès avec les structures modélisées ici.
Naturellement, vous pouvez effectuer autant d'ajustements que nécessaire.
Conception logique illustrative SQL-DDL
Par conséquent, sur la base du diagramme IDEF1X montré et décrit ci-dessus, j'ai écrit la disposition DDL logique qui est montrée comme suit (j'ai fourni des notes sous forme de commentaires qui expliquent certaines des caractéristiques que j'estime particulièrement importantes en ce qui concerne les tableaux, les colonnes et les contraintes déclaré):
-- 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)
);
Par conséquent, (1) chaque aspect singulier de la disposition logique ci-dessus porte une signification très précise à partir de (2) une caractéristique singulière de l'environnement commercial d'intérêt 7 - en accord avec l'esprit du cadre relationnel par le Dr Edgar Frank Codd -, parce que:
- Chaque table de base représente un type d'entité individuel.
- Chaque colonne représente une seule propriété du type d'entité respectif.
- Un type de données spécifique est fixé pour chaque colonne afin de garantir que toutes les valeurs qu'elle contient appartiennent à un ensemble particulier et correctement délimité a, que ce soit INT, DATETIME, CHAR, etc. (et espérons que MySQL incorporera enfin DOMAIN support dans une version proche).
- De multiples contraintes sont configurées (de manière déclarative) afin de garantir que les assertions sous forme de lignes conservées dans toutes les tables respectent les règles métier déterminées au niveau conceptuel.
Chaque ligne est destinée à transmettre une sémantique bien définie, par exemple, une Person
ligne est lue
La personne identifiée par PersonId r
est appelée par le prénom s
et le nom de famille t
, est née le BirthDate u
, a le GenderCode v
, les tweets sur le TwitterProfile w
, est accessible via PhoneNumber x
, est contactée via le EmailAddress y
et a été enregistrée sur CreatedDateTimez
.
Avoir une mise en page comme celle-ci est décidément favorable, car vous pouvez dériver de nouvelles tables (par exemple, des opérations SELECT qui rassemblent des colonnes FROM plusieurs tables à l'aide de la clause JOIN) qui - successivement - ont également une signification très précise (voir la section intitulé «Vues» ci-dessous).
Il convient de mentionner que, avec cette configuration, (i) une ligne représentant une instance de sous-type est identifiée par (ii) la même valeur PRIMARY KEY qui distingue la ligne indiquant l'occurrence de supertype complémentaire. Il est donc plus que opportun de noter que
- (a) attacher une colonne supplémentaire pour contenir les substituts générés et attribués par le système 8 à (b) les tableaux représentant les sous-types est (c) entièrement superflu .
Avec cette conception logique, si de nouveaux sous-types sont définis comme pertinents dans votre contexte commercial, vous devrez déclarer une nouvelle table de base, mais cela se produit également lorsque d'autres types de types d'entités sont jugés importants, de sorte que ladite situation serait, dans fait, ordinaire.
Vues
Afin de «récupérer», par exemple, toutes les informations qui correspondent à un acteur , un réalisateur ou un écrivain , vous pouvez déclarer certaines vues (c'est-à-dire des tables dérivées ou exprimables ) afin de pouvoir sélectionner directement à partir d'une seule ressource sans avoir à écrire le concernant JOINs à chaque fois; Par exemple, avec la VUE déclarée ci-dessous, vous pouvez obtenir les informations d' acteur «complètes» :
--
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;
--
Bien sûr, vous pouvez suivre une approche similaire afin de récupérer les informations "complètes" du réalisateur et du scénariste :
--
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;
--
J'ai posté toutes les instructions DDL et les vues DML ici discutées dans ce SQL Fiddle fonctionnant sur MySQL 5.6 afin que vous puissiez les voir et les tester «en action».
Notes de fin
1 Dans certaines techniques de modélisation conceptuelle, les associations supertype-sous-type sont appelées relations superclasse-sous-classe .
2 Bien que vous mentionniez qu'il existe en fait plus de rôles qu'une personne peut jouer, mais les trois que vous avez révélés sont assez bons pour discuter du scénario exposant plusieurs ramifications importantes .
3 Mais, comme vous l'avez noté, à l'avenir, un acteur pourrait éventuellement fournir des URL un à plusieurs .
4 La définition d'intégration pour la modélisation de l'information ( IDEF1X ) est une technique de modélisation hautement recommandable qui a été établie comme norme en décembre 1993 par le National Institute of Standards and Technology (NIST) des États-Unis . Il est basé sur (a) les premiers travaux théoriques rédigés par le seul auteur du modèle relationnel de données, c'est-à-dire le Dr EF Codd; sur (b) la vue de l' entité-relation , développée par Dr. PP Chen ; et également sur (c) la technique de conception de bases de données logiques, créée par Robert G. Brown.
5 La norme IDEF1X définit la migration de clé comme «le processus de modélisation consistant à placer la clé primaire d'une entité parent ou générique [c'est-à-dire, un super-type] dans son entité enfant ou catégorie [c'est-à-dire un sous-type] comme clé étrangère».
6 Dans IDEF1X, un nom de rôle est une étiquette distinctive attribuée à un attribut FK afin d'exprimer la signification qu'il détient dans le cadre de son type d'entité respectif.
7 Sauf, naturellement, pour les propriétés conceptuelles hypothétiques (et les colonnes logiques) Director.Etcetera et UserProfile.Etcetera , qui ne sont que des espaces réservés que j'ai utilisés pour exposer la possibilité d'ajouter plus de propriétés (et colonnes) qui s'appliquent au type d'entité conceptuel correspondant (et tableau logique).
8 Par exemple, ajouter une colonne supplémentaire avec l' attribut AUTO_INCREMENT à une table d'une base de données «en cours d'exécution» sur MySQL.