De acordo com minha interpretação de suas especificações, você deseja encontrar um método para implementar duas estruturas de supertipo-subtipo diferentes (mas conectadas ) .
Para expor uma abordagem para alcançar a tarefa mencionada, adicionarei ao cenário em questão os dois tipos clássicos de entidades hipotéticas denominados Foo
e Bar
, que detalharei a seguir.
Regras do negócio
Aqui estão algumas instruções que me ajudarão a criar um modelo lógico:
A Foo is either one Bar or one C
A Foo is categorized by one FooType
A Bar is either one A or one C
A Bar is classified by one BarType
Modelo lógico
E então, o modelo lógico IDEF1X [1] resultante é mostrado na Figura 1 (e você pode baixá-lo do Dropbox como um PDF também):
A adição de Foo e Bar
Não adicionei Foo
e Bar
fiz o modelo parecer melhor, mas para torná-lo mais expressivo. Considero que são importantes devido ao seguinte:
Como A
e B
compartilha o atributo nomeado E
, esse recurso sugere que eles são tipos de subentidade de um tipo distinto (mas relacionado) de conceito , evento , pessoa , medida etc., que eu representei por meio do Bar
tipo de superentidade que, por sua vez, é um tipo de subentidade de Foo
, que mantém o D
atributo na parte superior da hierarquia.
Como C
apenas compartilha um atributo com o restante dos tipos de entidade em discussão, ou seja, D
esse aspecto insinua que é um tipo de subentidade de outro tipo de conceito , evento , pessoa , medida , etc., então eu descrevi essa circunstância em virtude de o Foo
tipo de super entidade.
No entanto, essas são apenas suposições e, como um banco de dados relacional deve refletir com precisão a semântica de um determinado contexto de negócios , é necessário identificar e classificar todas as coisas de interesse em seu domínio específico, para que você possa captar com mais precisão .
Fatores importantes na fase de projeto
É bastante útil estar ciente do fato de que, deixando toda a terminologia de lado, um cluster exclusivo de supertipo-subtipo é um relacionamento comum. Vamos descrever a situação da seguinte maneira:
- Cada ocorrência de tipo de superentidade exclusiva está relacionada a apenas um complemento de tipo de subentidade .
Assim, há uma correspondência (ou cardinalidade) de um para um (1: 1) nesses casos.
Como você sabe nas postagens anteriores, o atributo discriminador (coluna, quando implementado) desempenha um papel primordial ao criar uma associação dessa natureza, porque indica a instância correta do subtipo ao qual o supertipo está conectado . A migração da CHAVE PRIMÁRIA de (i) o supertipo para (ii) os subtipos também é de importância primordial.
Estrutura DDL em concreto
E então eu escrevi uma estrutura DDL baseada no modelo lógico apresentado acima:
CREATE TABLE FooType -- Look-up table.
(
FooTypeCode CHAR(2) NOT NULL,
Description CHAR(90) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
CONSTRAINT PK_FooType PRIMARY KEY (FooTypeCode),
CONSTRAINT AK_FooType_Description UNIQUE (Description)
);
CREATE TABLE Foo -- Supertype
(
FooId INT NOT NULL, -- This PK migrates (1) to ‘Bar’ as ‘BarId’, (2) to ‘A’ as ‘AId’, (3) to ‘B’ as ‘BId’, and (4) to ‘C’ as ‘CId’.
FooTypeCode CHAR(2) NOT NULL, -- Discriminator column.
D INT NOT NULL, -- Column that applies to ‘Bar’ (and therefore to ‘A’ and ‘B’) and ‘C’.
CreatedDateTime DATETIME NOT NULL,
CONSTRAINT PK_Foo PRIMARY KEY (FooId),
CONSTRAINT FK_from_Foo_to_FooType FOREIGN KEY (FooTypeCode)
REFERENCES FooType (FooTypeCode)
);
CREATE TABLE BarType -- Look-up table.
(
BarTypeCode CHAR(1) NOT NULL,
Description CHAR(90) NOT NULL,
CONSTRAINT PK_BarType PRIMARY KEY (BarTypeCode),
CONSTRAINT AK_BarType_Description UNIQUE (Description)
);
CREATE TABLE Bar -- Subtype of ‘Foo’.
(
BarId INT NOT NULL, -- PK and FK.
BarTypeCode CHAR(1) NOT NULL, -- Discriminator column.
E INT NOT NULL, -- Column that applies to ‘A’ and ‘B’.
CONSTRAINT PK_Bar PRIMARY KEY (BarId),
CONSTRAINT FK_from_Bar_to_Foo FOREIGN KEY (BarId)
REFERENCES Foo (FooId),
CONSTRAINT FK_from_Bar_to_BarType FOREIGN KEY (BarTypeCode)
REFERENCES BarType (BarTypeCode)
);
CREATE TABLE A -- Subtype of ‘Bar’.
(
AId INT NOT NULL, -- PK and FK.
X INT NOT NULL, -- Particular column.
CONSTRAINT PK_A PRIMARY KEY (AId),
CONSTRAINT FK_from_A_to_Bar FOREIGN KEY (AId)
REFERENCES Bar (BarId)
);
CREATE TABLE B -- (1) Subtype of ‘Bar’ and (2) supertype of ‘A’ and ‘B’.
(
BId INT NOT NULL, -- PK and FK.
Y INT NOT NULL, -- Particular column.
CONSTRAINT PK_B PRIMARY KEY (BId),
CONSTRAINT FK_from_B_to_Bar FOREIGN KEY (BId)
REFERENCES Bar (BarId)
);
CREATE TABLE C -- Subtype of ‘Foo’.
(
CId INT NOT NULL, -- PK and FK.
Z INT NOT NULL, -- Particular column.
CONSTRAINT PK_C PRIMARY KEY (CId),
CONSTRAINT FK_from_C_to_Foo FOREIGN KEY (FooId)
REFERENCES Foo (FooId)
);
Com essa estrutura, você evita o armazenamento de marcas NULL em suas tabelas (ou relações ) de base, o que introduziria ambiguidade em sua base de dados.
Integridade, consistência e outras considerações
Depois de implementar seu banco de dados, você deve garantir que (a) cada linha de supertipo exclusivo seja sempre complementada por sua contraparte de subtipo correspondente e, por sua vez, garanta que (b) essa linha de subtipo seja compatível com o valor contido na coluna discriminadora de supertipo . Portanto, é bastante conveniente empregar o ACID TRANSACTIONS
para garantir que essas condições sejam atendidas no seu banco de dados.
Você não deve abandonar a solidez lógica, a auto-expressividade e a precisão do seu banco de dados, esses são aspectos que decididamente tornam seu banco de dados mais sólido.
As duas respostas postadas anteriormente já incluem pontos pertinentes que certamente valem a pena levar em consideração ao projetar, criar e gerenciar seu banco de dados e seus programas aplicativos.
Recuperando dados por meio das definições de VIEW
Você pode configurar algumas visualizações que combinam colunas dos diferentes grupos de supertipos e subtipos , para recuperar os dados em mãos sem, por exemplo, escrever as cláusulas JOIN necessárias sempre. Dessa forma, você pode SELECIONAR diretamente DA VISTA (uma relação ou tabela derivada ) de interesse com facilidade.
Como você pode ver, "Ted" Codd foi, sem dúvida, um gênio. As ferramentas que ele legou são bastante fortes e elegantes e, é claro, estão bem integradas entre si.
Recursos relacionados
Se você deseja analisar algum banco de dados extenso que envolva relacionamentos supertipo-subtipo, você achará valiosas as respostas extraordinárias propostas por @PerformanceDBA para as seguintes perguntas sobre estouro de pilha:
Nota
1. A Definição de Integração para Modelagem de Informações ( IDEF1X ) é uma técnica de modelagem de dados 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 . É solidamente baseado em (a) o material teórico inicial criado pelo Dr. EF Codd; em (b) a entidade-relacionamento vista de dados, desenvolvido por Dr. PP Chen ; e também (c) a Logical Database Design Technique, criada por Robert G. Brown. Vale ressaltar que o IDEF1X foi formalizado por meio de lógica de primeira ordem.