Quelle est la meilleure façon d'implémenter L'Association polymorphique dans SQL Server?

j'ai des tonnes de cas où je dois implémenter une sorte d'Association polymorphe dans ma base de données. Je perds toujours beaucoup de temps à réfléchir à toutes les options à nouveau. Voici les 3 je pense. J'espère qu'il y a une bonne pratique pour SQL Server.

Voici l'approche à colonnes multiples

Multiple Column approach

, Voici la pas de clé étrangère approche

No Foreign Key Approach

et voici l'approche de la table de base

Base table approach

49
demandé sur Mark 2011-08-09 21:28:55

9 réponses

les deux approches les plus courantes sont le tableau par classe (c.-à-d. Un tableau pour la classe de base et un autre tableau pour chaque sous-classe qui contient les colonnes supplémentaires nécessaires pour décrire la sous-classe) et le tableau par hiérarchie (c.-à-d. toutes les colonnes d'un tableau, avec une ou plusieurs colonnes pour permettre la discrimination des sous-classes. Quelle est la meilleure approche dépend vraiment des détails de votre application et de votre stratégie d'accès aux données.

vous auriez Table par Classe dans votre premier exemple en inversant la direction du FK et en supprimant les identifiants supplémentaires du parent. Les deux autres sont essentiellement des variantes de tableau par classe.

3
répondu cmsjr 2011-08-09 18:35:35

un autre nom commun pour ce modèle est le modèle Supertype, où l'on a un ensemble de base d'attributs qui peuvent être élargis en se joignant à une autre entité. Dans les livres Oracle, il est enseigné à la fois comme un modèle logique et la mise en œuvre physique. Le modèle sans les relations permettrait aux données de se transformer en États invalides et dossiers orphelins je validerais fortement les besoins avant de choisir ce modèle. Le modèle supérieur avec la relation stockée dans l'objet de base causerait des nulls, et dans un cas là où les champs étaient mutuellement exclusifs, vous auriez toujours un nul. Le diagramme du bas où la clé est appliquée dans l'objet enfant éliminerait les nulls mais ferait aussi de la dépendance une dépénendance douce et permettrait aux orphelins si la cascade n'était pas appliquée. Je pense que l'évaluation de ces traits vous aidera à choisir le modèle qui convient le mieux. J'ai utilisé tous les trois dans le passé.

2
répondu Daren C 2016-05-24 14:18:49

j'ai utilisé la solution suivante pour résoudre un problème similaire:

plusieurs-plusieurs design basé: même si la relation est un 1-Beaucoup entre un objet et quelque chose, il est équivalent à une relation beaucoup-beaucoup avec une modification de la PK de la table de relation.

D'abord je crée une table de relation entre un ObjectN et quelque chose par objet et ensuite j'utilise la colonne Something_ID comme PK.

C'est le DDL du Quelque chose-Objet1 relation qui est la même pour Objet2 et Objet3 ainsi :

CREATE TABLE Something
(
    ID INT PRIMARY KEY,
    .....
)

CREATE TABLE Object1
(
   ID INT PRIMARY KEY,
   .....
)

CREATE TABLE Something_Object1
(
    Something_ID INT PRIMARY KEY,
    Object1_ID INT NOT NULL,
    ......

    FOREIGN KEY (Something_ID) REFERENCES Something(ID),
    FOREIGN KEY (Object1_ID) REFERENCES Object1(ID)
)

Plus de détails et des exemples d'autres options possibles dans ce billet plusieurs-foreign-keys-pour-la-même-business-la règle

1
répondu Samir 2018-07-14 13:20:27

selon moi, votre premier type d'approche est la meilleure façon de définir les données ainsi que vos classes, mais comme toutes vos données primaires devraient être disponibles pour l'enfant.

ainsi vous pouvez vérifier votre exigence et définir la base de données.

0
répondu Umakanta.Swain 2015-10-10 01:53:24

j'ai utilisé ce qu'on pourrait appeler l'approche de la table de base. Par exemple, j'avais des tables pour les noms, les adresses, et les numéros de téléphone, chacun avec une identité comme PK. Puis j'ai eu une table entity entity principale entity (entityID), et une table linking: attribut(entityKey, attributeType, attributeKey), dans laquelle l'attributeKey pouvait pointer vers n'importe laquelle des trois premières tables, en fonction de l'attributype.

quelques avantages: permet autant de noms, d'adresses et de numéros de téléphone par entité comme on les aime, facile d'ajouter de nouveaux types d'attributs, de l'extrême normalisation, facile à mine attributs communs (c'est à dire identifier les doublons de personnes), d'autres propres à l'entreprise des avantages de sécurité

inconvénients: les requêtes assez complexes pour construire des ensembles de résultats simples ont rendu la gestion difficile (i.e. j'ai eu de la difficulté à embaucher des gens avec suffisamment de bons côtelettes T-SQL); la performance est optimale pour des cas D'utilisation très spécifiques plutôt que Générale; l'optimisation des requêtes peut être délicate

ayant vécu avec cette structure pendant plusieurs années sur une carrière beaucoup plus longue, j'hésiterais à l'utiliser à nouveau à moins d'avoir les mêmes contraintes de logique d'affaires bizarres et les modèles d'accès. Pour l'usage général, je recommande fortement vos tableaux dactylographiés référencent directement vos entités. C'est-à-dire entité(entityID), nom(NameID, EntityID, Name), téléphone(PhoneID, EntityID, Phone), E-Mail(EmailID, EntityID, e-mail). Vous aurez quelques répétitions de données et quelques colonnes communes, mais ce sera beaucoup plus facile à programmer et optimiser.

0
répondu JackOfAll 2016-04-28 07:54:10

L'approche 1 est la meilleure, mais l'association entre quelque chose et object1, object2 ,object3 devrait être un à un.

je veux dire FK enfant (objet1, objet2, objet3) table doit être non null clé unique ou de clé Primaire pour la table enfant.

objet1, objet2 ,objet3 peut avoir Polymorphes la valeur de l'objet .

0
répondu sandeep rawat 2016-05-04 15:12:21

il n'existe pas de meilleure pratique unique ou universelle pour y parvenir. Tout dépend du type d'accès, les applications ont besoin.

mon conseil serait de faire un aperçu sur le type prévu d'accès à ces tableaux:

  1. utiliserez-vous une couche ou, des procédures stockées ou du SQL dynamique?
  2. A quel nombre de disques vous attendez-vous?
  3. Quel est le niveau de différence entre le différentes sous-classes? Le nombre de colonnes?
  4. ferez-vous des regroupements ou d'autres déclarations complexes?
  5. aurez-vous un entrepôt de données pour la déclaration ou non?
  6. aurez-vous souvent besoin de traiter des enregistrements de différentes sous-classes en un seul lot? ...

à partir des réponses à ces questions, nous pourrions trouver une solution appropriée.

une possibilité supplémentaire de stocker les propriétés spécifiques aux sous-classes consistent à utiliser une table avec des paires nom/valeur. Cette approche peut être particulièrement utile s'il existe un grand nombre de sous-classes différentes ou lorsque les champs spécifiques dans les sous-classes sont utilisés peu fréquemment.

0
répondu tomislav_t 2016-07-28 13:02:27

j'ai utilisé la première approche. Sous des charges extrêmes, la table" quelque chose " devient un goulot d'étranglement.

j'ai pris l'approche D'avoir le modèle DDL pour mes différents objets avec les spécialisations d'attribut étant ajouté à la fin de la définition de tableau.

au niveau DB si j'avais vraiment besoin de représenter mes différentes classes comme un enregistreur "quelque chose" alors je mets une vue sur le dessus d'eux

SELECT "Something" fields FROM object1
UNION ALL
SELECT "Something" fields FROM object2
UNION ALL
SELECT "Something" fields FROM object3

Le défi est de savoir comment vous assignez une clé primaire non-Clash étant donné que vous avez trois objets indépendants. Typiquement les gens utilisent un UUID / GUID mais dans mon cas la clé était un entier 64 bits généré dans une application basée sur un temps et une machine afin d'éviter les conflits.

si vous suivez cette approche, vous évitez le problème de l'objet" quelque chose " qui provoque le verrouillage/blocage.

si vous voulez modifier l'objet" quelque chose " alors cela peut être maladroit maintenant vous avez trois objets indépendants, ce qui obligera leur structure pour être modifié.

en résumé. La première option fonctionne très bien dans la plupart des cas, mais sous une charge très lourde, vous pouvez observer un blocage de verrouillage qui nécessite la séparation de la conception.

0
répondu Dave Poole 2017-01-27 17:00:23

approche 1 avec des touches étrangères à colonnes multiples est la meilleure. Parce que de cette façon vous pouvez avoir des connexions prédéfinies avec d'autres tables Et cela rend beaucoup plus facile pour les scripts de sélectionner, d'insérer et de mettre à jour des données.

0
répondu Archi 2017-02-05 15:24:53