9
votes

Un à plusieurs, mais en identifiant l'un des nombreux comme la «défaillance»

J'ai une table personne et adresse . Une personne peut avoir plusieurs les enregistrements , donc une simple relation 1 .. * relation avec adresse avoir un champ référençant "Person ID".

Maintenant, pour une personne donnée Je souhaite identifier leur adresse "par défaut" ou "primaire" adresse .

J'ai proposé deux idées, mais je ne suis pas convaincu non plus. Avant de décider, quelqu'un peut-il offrir des commentaires en ce qui concerne les problèmes potentiels que je pourrais faire face à la ligne avec l'une ou l'autre option ...

(a). Pourrait avoir un «ID d'adresse par défaut» sur personne qui stockerait le ID de l'adresse adresse . Piège possible ici est que une adresse n'appartenant pas à cette personne pourrait être définie ici, donc aurait besoin d'une contrainte de contrôle supplémentaire pour l'empêcher.

(b). Pourrait avoir un drapeau "par défaut" sur la table adresse , mais cela a le Possibilité de permettre plusieurs sélections, de même aurait besoin de vérifie de sorte que lors de la réglage du drapeau, il est également effacé sur tous enregistrements appartenant à la même personne .

n'importe quel


5 commentaires

Jusqu'à présent, je suis penché vers les solutions (b) -Type ci-dessous, mais je remarque que cela n'offre pas de manière évidente d'appliquer qu'un utilisateur doit avoir au moins une adresse qui serait souhaitable. Avec (a), il s'agit simplement d'un cas de «identifiant d'adresse par défaut» non nulle.


Si vous allez avec (a) et faites l'identifiant d'adresse 'par défaut »non NULL, vous aurez des problèmes graves en insertion et en supprimant les 2 tables. Les chemins circulaires dans les tables références ne sont pas de joie.


Je suis d'accord, mais y a-t-il une meilleure alternative pour que la personne ait au moins 1 adresse?


Utilisez une relation normale 1: N entre personne et adresse et assurez-vous via des transactions / procédures stockées que tous les insertions / suppressions / mises à jour dans les 2 tables conservent cette contrainte. (ou avec 3 tables, de la même manière que toutes les personnes ont au moins une adresse et exactement une adresse par défaut)


Les instructions DDL définissent 1 :: 0..n et 1 :: 0..1 relations. Les rendre stricts 1 :: 1..n ou 1 :: 1 ne peut pas être effectué par DDL seul.


7 Réponses :


0
votes

option (a) - stocker une référence à une adresse comme une adresse par défaut pourrait entraîner un problème si vous modifiez jamais les valeurs de l'adresse par défaut.


1 commentaires

Merci pour votre commentaire, mais pas sûr de bien comprendre. Pourriez-vous élaborer?



0
votes

Je pourrais aller avec un sous-ensemble de B, j'ajouterais un champ Adressype sur le tableau d'adresses où vous pourriez définir le type primaire et secondaire ou de type générique, vous pouvez également vous préparer à des types futurs. d'adresses sans avoir à modifier le schéma.


0 commentaires

2
votes

J'irais avec (b) puis protégeriez le réglage du bit par défaut.

de lire vos commentaires sur votre question, je souhaite ajouter que pour appliquer qu'il existe toujours au moins 1 adresse définie avec le bit par défaut, vous devez simplement gérer cela dans votre procédure stockée.

quelque chose comme :

pour un insert: xxx

pour une mise à jour: xxx

en plus, vous pourrait également empêcher cela de votre interface utilisateur, mais cela ne fait pas mal d'avoir une couche supplémentaire de protection dans la DB.


2 commentaires

C'est à peu près la solution que j'ai assurée. Je pense que les problèmes que j'avais eues étaient que j'essayais de faire respecter toutes les exigences possibles de DDL, ce qui entraînait un schéma qui était rapide devenant ingérable. Je pense que j'ai appris une leçon beaucoup plus importante de ce poste que la question initiale que j'ai posée.


@Gavin Ceci est facilement exécutoire à la couche DB avec une contrainte.



0
votes

Nous avons un champ d'indicateur par défaut et un déclencheur qui veille à ce que l'un et un seul enregistrement a la valeur par défaut de 1. Assurez-vous d'écrire la gâchette pour gérer plusieurs inserts d'enregistrement / mises à jour et les supprimer et les tester. Donc, s'il s'agit du premier enregistrement inséré, le champ est automatiquement défini sur 1. Si l'enregistrement avec le champ défini sur ONE est supprimé, nous avons une règle d'entreprise ineh déclencheur qui détermine le record restant obtiendra la valeur par défaut. Si un enregistrement différent est mis à jour à 1, l'enregistrement existant que le 1 est mis à jour pour avoir 0 sur le champ. Si vous n'utilisez pas de déclencheur, il est fort probable que vous aurez des problèmes d'intégrité des données à un moment donné.


2 commentaires

J'ai eu une tonne de problèmes d'écablabilité avec des déclencheurs. Y a-t-il une façon spéciale de les faire pour éviter cela? J'ai plutôt dû faire cela comme je l'ai fait dans ma réponse. Cependant, j'aimerais que vous puissiez me prouver mal, car j'adore les déclencheurs.


Les déclencheurs gravement écrits peuvent avoir des problèmes de scalibilty, en particulier si quelqu'un choisit de traiter un enregistrement à un moment plutôt que dans des ensembles ou des enregistrements de mise à jour dont vous n'avez pas besoin de mise à jour, etc. (i une fois dans la réparation d'un déclencheur qui a traité plusieurs insertions d'enregistrement à travers une Curseur, le modifiant à une gâchette à consigne amélioré les performances de 45 minutes à 40 secondes pour un insert d'enregistrement 40K). Les déclencheurs doivent être très optimisés pour la performance car ils ajouteront un temps à chaque action. Ils doivent également être testés soigneusement pour s'assurer que tout type d'action sur la table peut être correctement manipulé.



0
votes

au lieu de (a) pourrait avoir un "ID d'adresse par défaut" sur la personne Que diriez-vous d'un booléen? isdefaulleaddr

Pour expliquer davantage, au lieu d'avoir un champ comme DefaultAddRessID dans la table Personal, vous pouvez simplement avoir un champ booléen dans la table de personnes, comme IsdefaultAddress. Sa valeur est vraie s'il s'agit de l'adresse par défaut pour cette personne, sinon, FALSE.

htth


1 commentaires

Merci pour votre commentaire, mais pas sûr de comprendre votre suggestion. Pourriez-vous expliquer plus loin?



2
votes

Une autre option est (normalisant les données par) Ajout d'une autre table DefaultAddress : xxx


2 commentaires

Cela pose un problème dans lequel une ligne dans le tableau adresse existe, mais la ligne correspondante dans défaitAddress ne fait pas.


@Dal, l'idée est que le défaitAddress est peuplé avec des données de (une ligne de) adresse .



0
votes

J'irais pour l'option B avec un index unique sur adresse PersonID et par défaut par défaut par défaut = vrai . Quelque chose comme: xxx

De cette façon, vous assurez qu'il n'y a plus d'adresse par défaut pour une personne.

S'il arrive qu'aucune adresse n'est pas par défaut, choisissez le premier un.


0 commentaires