De acordo com minha interpretação de sua descrição do contexto de negócios de interesse, você está lidando com uma estrutura de supertipo-subtipo 1 , em que (a) Ator , Diretor e Escritor são subtipos de entidade de (b) Pessoa , supertipo de entidade e (c) os referidos subtipos não são mutuamente exclusivos.
Dessa forma, se você estiver interessado em construir um banco de dados relacional que espelhe esse cenário com precisão - e, portanto, espere que ele funcione como tal -, seus esclarecimentos a seguir são bastante significativos em relação aos pontos anteriores, porque têm implicações em (1) os níveis conceitual e (2) lógico de representação do banco de dados em questão:
[…] Tabelas adicionais para cada um dos respectivos tipos de usuário, cada um com seu próprio conjunto de colunas exclusivo.
[…] Existem apenas quatro tipos de usuários que são relevantes. Há uma chance externa de que esse número possa aumentar, mas a probabilidade é baixa - e, nesse caso, seria por um número muito pequeno.
Vou elaborar todos esses aspectos e vários outros fatores críticos nas seções abaixo.
Regras do negócio
Para definir primeiro o esquema conceitual correspondente - que pode ser usado como referência subsequente para que você possa adaptá-lo para garantir que ele atenda aos requisitos informacionais exatos - , formulamos algumas regras de negócios que são de particular importância:
- Uma Pessoa pode desempenhar uma ou duas ou três funções (um para todos) 2 . Em outras palavras, uma Pessoa pode ser
- um ator e
- um diretor e
- um escritor .
- Uma Pessoa pode efetuar login via UserProfile zero ou um .
- Um ator fornece um ou dois ou três URLs 3 .
- Um ator é agrupado por uma etnia .
- Uma etnia agrupa zero ou um ou muitos atores .
- Um escritor é baseado em um local .
- Um local é a base de zero ou um ou mais escritores .
Diagrama do IDEF1X expositivo
Em seguida, criei o diagrama IDEF1X 4 mostrado na Figura 1 , que agrupa todas as formulações acima, juntamente com outras regras que parecem pertinentes:
Como demonstrado, o supertipo Pessoa (i) possui sua própria caixa, (ii) possui as propriedades ou atributos que se aplicam a todos os subtipos e (iii) apresenta linhas que o conectam às caixas de cada subtipo.
Por sua vez, todo subtipo (a) aparece em sua própria caixa dedicada e (b) mantém exclusivamente suas propriedades aplicáveis. A CHAVE PRIMÁRIA do supertipo, PersonId , migra 5 para os subtipos com os nomes de função 6 ActorId , DirectorId e WriterId, respectivamente.
Além disso, evitei acoplar Person ao tipo de entidade UserProfile , que permite separar todas as implicações contextuais, associações ou relacionamentos etc. A propriedade PersonId foi migrada para UserProfile com o nome de função UserId .
Você declara no corpo da pergunta que
E todos os atores deverão incluir pelo menos um URL para qualquer um dos outros perfis de atores on-line; Atualmente, existem três que eles podem incluir, mas esse número pode aumentar.
… Portanto, o URL é um tipo de entidade por direito próprio e está diretamente associado ao subtipo de ator , de acordo com esta citação.
E, nos comentários , você especifica que
[…] Um ator terá um tiro na cabeça (foto), enquanto um escritor não terá […]
… Então, entre outros recursos, incluí o Headshot como uma propriedade do tipo de entidade ator .
Quanto aos tipos de entidade Etnia e Localização , é claro que eles podem envolver organizações mais complexas (por exemplo, um Ator pode pertencer a um, dois ou mais grupos étnicos diferentes em proporções distintas, e um Escritor pode basear-se em um local que requer gravação país, região administrativa, município etc.), mas parece que as necessidades do seu contexto de negócios são cobertas com êxito pelas estruturas aqui modeladas.
Naturalmente, você pode fazer quantos ajustes forem necessários.
Projeto lógico SQL-DDL ilustrativo
Consequentemente, com base no diagrama IDEF1X mostrado e descrito acima, escrevi o layout DDL lógico que é mostrado a seguir (forneci notas como comentários que explicam algumas das características que considero particularmente importantes em relação às tabelas, colunas e restrições declarado):
-- 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)
);
Portanto, (1) todo aspecto singular do layout lógico acima possui um significado muito preciso de (2) uma característica singular do ambiente de negócios de interesse 7 - de acordo com o espírito da estrutura relacional do Dr. Edgar Frank Codd -, Porque:
- Cada tabela base representa um tipo de entidade individual.
- Cada coluna representa uma única propriedade do respectivo tipo de entidade.
- Um tipo de dados específico é fixado para cada coluna , a fim de garantir que todos os valores contidos pertençam a um conjunto a, específico e adequadamente delimitado, seja INT, DATETIME, CHAR, etc (e esperemos que o MySQL finalmente incorpore DOMAIN suporte em versão de futuro próximo).
- Múltiplas restrições são configuradas (declarativamente) para garantir que as asserções em forma de linhas retidas em todas as tabelas estejam em conformidade com as regras de negócios determinadas no nível conceitual.
Cada linha destina-se a transmitir semânticas bem definidas, por exemplo, uma Person
linha é lida
A Pessoa identificada por PersonId r
é chamada pelo Nome s
e o Sobrenome t
, nasceu em BirthDate u
, possui o GenderCode v
, os tweets no TwitterProfile w
, é alcançado através do PhoneNumber x
, é contatado pelo EmailAddress y
e registrado no CreatedDateTimez
.
Ter um layout como esse é decididamente favorável, pois você pode derivar novas tabelas (por exemplo, operações SELECT que reúnem colunas FROM várias tabelas com a ajuda da cláusula JOIN) que - em sucessão - também possuem um significado muito preciso (consulte a seção intitulado "Visualizações" abaixo).
É importante mencionar que, com essa configuração, (i) uma linha representando uma instância de subtipo é identificada por (ii) o mesmo valor PRIMARY KEY que distingue a linha que indica a ocorrência complementar do supertipo. Portanto, é mais do que oportuno observar que
- (a) anexar uma coluna extra para conter substitutos gerados e atribuídos pelo sistema 8 a (b) as tabelas que representam os subtipos são (c) inteiramente supérfluas .
Com esse design lógico, se novos subtipos forem definidos como relevantes em seu contexto de negócios, você deverá declarar uma nova tabela base, mas isso acontecerá também quando outros tipos de tipos de entidade forem considerados significativos, portanto, a situação seria fato, comum.
Visualizações
A fim de “buscar”, por exemplo, toda a informação que corresponde a um Ator , Diretor ou escritor , você pode declarar alguns pontos de vista (isto é, derivado ou exprimíveis tabelas) de modo que você pode selecionar diretamente a partir de um único recurso sem ter que escrever o sobre JOINs sempre; por exemplo, com a VIEW declarada abaixo, você pode obter as informações “completas” do ator :
--
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;
--
Obviamente, você pode seguir uma abordagem semelhante para recuperar as informações “completas” do diretor e escritor :
--
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;
--
Publiquei todas as instruções DDL e as visualizações DML aqui discutidas neste SQL Fiddle em execução no MySQL 5.6 para que você possa vê-las e testá-las "em ação".
Notas finais
1 Em algumas técnicas de modelagem conceitual, as associações supertipo-subtipo são chamadas de relacionamentos superclasse-subclasse .
2 Embora você mencione que existem de fato mais funções que uma Pessoa pode desempenhar, mas as três que você revelou são boas o suficiente para discutir o cenário que expõe várias ramificações importantes .
3 Mas, como você observou, no futuro um ator poderá eventualmente fornecer URLs um para muitos .
4 Definição de Integração para Modelagem de Informações ( IDEF1X ) é uma técnica de modelagem altamente recomendável que foi estabelecida como padrão em dezembro de 1993 pelo Instituto Nacional de Padrões e Tecnologia (NIST) dos Estados Unidos . É baseado em (a) os primeiros trabalhos teóricos de autoria do único autor do modelo relacional de dados, ou seja, Dr. EF Codd; (b) a visão de relacionamento entre entidades , desenvolvida pelo Dr. PP Chen ; e também (c) a Logical Database Design Technique, criada por Robert G. Brown.
5 O padrão IDEF1X define a migração de chave como “O processo de modelagem de colocar a chave primária de uma entidade pai ou genérica [isto é, um supertipo] em sua entidade filha ou categoria [ou seja, um subtipo] como uma chave estrangeira”.
6 No IDEF1X, um nome de função é um rótulo distinto atribuído a um atributo FK para expressar o significado que ele possui no escopo de seu respectivo tipo de entidade.
7 Exceto, naturalmente, as propriedades conceituais hipotéticas (e as colunas lógicas) Director.Etcetera e UserProfile.Etcetera , que são meramente espaços reservados que eu usei para expor a possibilidade de adicionar mais propriedades (e colunas) que se aplicam ao tipo de entidade conceitual correspondente (e tabela lógica).
8 Por exemplo, anexando uma coluna adicional com o atributo AUTO_INCREMENT a uma tabela de um banco de dados "em execução" no MySQL.