Posso decompor esta tabela sem perdas?

10

Eu me deparei com um problema de design de banco de dados que está fora do meu alcance, e meu guru do DBA preferencial está fora de campo.

Em essência, eu tenho uma tabela com a seguinte chave primária (PK por brevidade):

child_id   integer
parent_id  integer
date       datetime

child_ide parent_idsão chaves estrangeiras para tabelas de entidades. A tabela "filho" em si também contém uma chave estrangeira para a tabela "pai", e eis que cada uma child_idsempre faz referência à mesma parent_idque o esperado pela tabela acima. Na verdade, acontece que há algum código extra mantendo os dois em sincronia.

O que faz esse novato de normalização super entusiasmado dizer "Devo remover a redundância!"

Decomponho o seguinte:

Table_1 PK:
child_id   integer
date       datetime

Table_2 PK:
parent_id  integer
date       datetime

Table_3: (already exists)
child_id   integer PRIMARY KEY
parent_id  integer FOREIGN KEY

E eis que, quando uno esses caras da maneira natural, recupero a tabela original. É o meu entendimento que torna este 5NF.

No entanto, agora percebo que há uma regra de negócios oculta.

Normalmente, as datas associadas a um determinado child_iddevem ser um subconjunto das datas associadas ao correspondente parent_id. Você pode ver que a primeira tabela impõe essa regra.

Minha decomposição não impõe a regra, porque você pode adicionar livremente à Tabela 1 até que as datas fiquem muito grandes.

O que me leva aqui, com as seguintes perguntas:

  1. Esta decomposição é 5NF? Embora eu diga que permite anomalias de inserção, também parece seguir o exemplo do Wiki, que segue este guia . A frase (ênfase minha) "podemos reconstruir todos os fatos verdadeiros a partir de uma forma normalizada que consiste em três tipos de registros separados" me dá uma pausa especial, pois, não importa a quantidade de lixo que eu bombeie Table_1, a junção natural ainda a ignora.

  2. Supondo que eu não goste desta decomposição (eu não). Reconheço livremente que a solução prática é deixar a tabela e o código como estão. Mas, em teoria, existe uma maneira de decompor e / ou adicionar restrições de modo que eu me afaste da primeira tabela e preserve minhas regras de negócios?

Trevor
fonte
11
Quais são as chaves na sua tabela original? Que dependências ele deveria satisfazer? Parece que você está dizendo que child_id-> parent_id, nesse caso child_id e parent_id não podem fazer parte da mesma chave nessa tabela.
Nvogel
11
@ Trevor: Você já revisou as respostas aqui? Visto pela última vez 19 minutos depois de perguntar. As respostas vieram depois.
gbn 27/08

Respostas:

9

A normalização é baseada em dependências funcionais. Dependências funcionais têm a ver com semântica; eles têm a ver com o que os dados significam . Quando você simplifica um problema do mundo real para o nível "parent_id, child_id, date" e não inclui nenhum dado de amostra, você realmente limita a quantidade de ajuda que um designer de banco de dados consciente pode oferecer.

O fato de você ter uma chave {child_id, parent_id, date} em uma tabela e ter (ao que parece) um par exclusivo {child_id, parent_id} na tabela filho não significa necessariamente que parte da combinação é redundante . Isso pode significar que na tabela que possui {child_id, parent_id, date} como chave primária, o par de atributos {child_id, parent_id} deve fazer referência à tabela filho em primeiro lugar.

Se for esse o caso, você pode usar FOREIGN KEY (child_id, parent_id) REFERENCES child (child_id, parent_id). Para fazer isso, você precisa de uma restrição UNIQUE no par de colunas (child_id, parent_id) na tabela "child", o que não deve ser um problema se child_id for sua chave primária.

Mas não há como saber sem saber o que os dados significam, e você é o único nesse segmento que sabe disso. (Mas ficaríamos felizes em deixar você explicar isso para nós.)

No que diz respeito à tabela original, você parece estar dizendo que child_id -> parent_id. Se for esse o caso, por que parent_id está na tabela original em primeiro lugar? Por que a chave não é apenas (child_id, date), com uma referência de chave estrangeira à tabela "child"? Parece-me que o tipo de redundância de que você está falando pode ser resolvido soltando a coluna "parent_id".

SQL DDL e dados de amostra na forma de instruções INSERT nos ajudam a ajudá-lo. As instruções DDL e INSERT são mais precisas que as descrições.

Mike Sherrill 'Rechamada de gato'
fonte
11
+2 para lembrete de "dependência funcional"
jcolebrand
3

Tente isso ...

  • Adicionar restrição exclusiva (child_id,parent_id)na tabela filho
  • Sua tabela atual (PK,FK:child_id, PK,FK:parent_id, PK:date)permanece como está, o FK está em 2 colunas para a nova restrição exclusiva

ou

  • Remova o FK da tabela filho atual
  • Crie uma nova tabela (PK,FK:child_id, FK:parent_id)1: 1 com filho
  • Sua tabela atual (PK,FK: child_id, PK,FK: parent_id, PK:date)permanece como está. mas o FK está em 2 colunas na nova tabela

Se nada mais, pode inspirar você ...

Se entendi corretamente, ele removerá redundância e código ...

gbn
fonte