Puis-je décomposer sans perte cette table?

10

Je suis tombé sur un problème de conception de base de données hors de ma ligue et mon gourou DBA est en train de faire des exercices d'incendie.

En substance, j'ai une table avec la clé primaire suivante (PK pour la brièveté):

child_id   integer
parent_id  integer
date       datetime

child_idet parent_idsont des clés étrangères aux tables d'entités. La table "enfant" elle-même contient également une clé étrangère vers la table "parent", et lo, chacune fait child_idtoujours référence à la même chose parent_idque prévu par le tableau ci-dessus. En fait, il se trouve qu'il y a du code supplémentaire qui maintient les deux synchronisés.

Ce qui fait dire à ce novice trop enthousiaste de la normalisation: «Je devrais plutôt supprimer la redondance!

Je me décompose comme suit:

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

Et voilà, quand je rejoins ces gars ensemble de façon naturelle, je récupère la table d'origine. C'est ma compréhension qui fait ce 5NF.

Cependant, maintenant je me rends compte qu'il existe une règle commerciale cachée.

Normalement, les dates associées à un donné child_iddoivent être un sous-ensemble des dates associées au correspondant parent_id. Vous pouvez voir que le premier tableau applique cette règle.

Ma décomposition n'applique pas la règle, car vous pouvez ajouter librement au tableau 1 jusqu'à ce que les dates deviennent trop grandes.

Ce qui m'amène ici, avec les questions suivantes:

  1. Cette décomposition est-elle 5NF? Bien que je dirais qu'il permet des anomalies d'insertion, il semble également suivre l'exemple du wiki, qui suit lui-même ce guide . L'expression ( je souligne) "nous pouvons reconstruire tous les faits réels à partir d'une forme normalisée composée de trois types d'enregistrement distincts" me donne une pause spéciale, car peu importe la quantité de déchets dans lesquels je pompe Table_1, la jointure naturelle l'ignore toujours.

  2. Supposons que je n'aime pas cette décomposition (je n'aime pas). Je reconnais librement que la solution pratique est de laisser la table et le code tels quels. Mais, en théorie, existe-t-il un moyen de décomposer et / ou d'ajouter des contraintes pour que je m'éloigne de la première table et préserve mes règles métier?

trevor
la source
1
Quelles sont les clés de votre table d'origine? Quelles dépendances est-il censé satifier? Vous semblez dire que child_id-> parent_id, auquel cas child_id et parent_id ne peuvent pas tous deux faire partie de la même clé dans cette table.
nvogel
1
@trevor: Avez-vous déjà examiné les réponses ici? Vue la dernière fois à 19 minutes après avoir demandé. Les réponses sont venues plus tard.
gbn

Réponses:

9

La normalisation est basée sur des dépendances fonctionnelles. Les dépendances fonctionnelles ont à voir avec la sémantique; ils ont à voir avec ce que les données des moyens . Lorsque vous simplifiez un problème du monde réel au niveau de "parent_id, child_id, date" et que vous n'incluez aucun exemple de données, vous limitez vraiment l'aide qu'un concepteur de base de données consciencieux peut vous apporter.

Le fait que vous ayez une clé {child_id, parent_id, date} dans une table et que vous ayez (il semble) une paire unique {child_id, parent_id} dans la table enfant ne signifie pas nécessairement qu'une partie de la combinaison est redondante . Cela peut signifier que dans la table qui a {child_id, parent_id, date} comme clé primaire, la paire d'attributs {child_id, parent_id} doit référencer la table enfant en premier lieu.

Si tel est le cas, vous pouvez utiliser FOREIGN KEY (child_id, parent_id) REFERENCES child (child_id, parent_id). Pour ce faire, vous avez besoin d'une contrainte UNIQUE sur la paire de colonnes (child_id, parent_id) dans la table "child", ce qui ne devrait pas être un problème si child_id est sa clé primaire.

Mais il n'y a aucun moyen de savoir sans savoir ce que signifient les données, et vous êtes le seul dans ce fil qui le sait. (Mais nous serions heureux de vous laisser nous l'expliquer.)

En ce qui concerne la table d'origine, vous semblez dire que child_id -> parent_id. Si tel est le cas, pourquoi parent_id dans la table d'origine en premier lieu? Pourquoi la clé n'est-elle pas juste (child_id, date), avec une référence de clé étrangère à la table "enfant"? Il me semble que le type de redondance dont vous parlez pourrait être résolu en supprimant la colonne "parent_id".

Le DDL SQL et des exemples de données sous forme d'instructions INSERT nous aident à vous aider. Les instructions DDL et INSERT sont plus précises que les descriptions.

Mike Sherrill 'Cat Recall'
la source
1
+2 pour le rappel "dépendance fonctionnelle"
jcolebrand
3

Essaye ça...

  • Ajouter une contrainte unique à (child_id,parent_id)la table enfant
  • Votre table actuelle (PK,FK:child_id, PK,FK:parent_id, PK:date)reste telle quelle, le FK est sur 2 colonnes à la nouvelle contrainte unique

ou

  • Supprimer le FK de la table enfant actuelle
  • Créer une nouvelle table (PK,FK:child_id, FK:parent_id)1: 1 avec enfant
  • Votre table actuelle (PK,FK: child_id, PK,FK: parent_id, PK:date)reste telle quelle. mais le FK est sur 2 colonnes vers la nouvelle table

Si rien d'autre, cela peut vous inspirer ...

Si j'ai bien compris, cela supprimera la redondance et le code ...

gbn
la source