Question

J'ai une structure de table. Je ne sais pas trop comment créer le meilleur moyen.

En gros, j'ai deux tables, tblSystemItems et tblClientItems. J'ai une troisième table qui a une colonne qui fait référence à un «élément». Le problème est que cette colonne doit référencer un élément système ou un élément client - peu importe lequel. Les éléments système ont des clés dans la plage 1..2 ^ 31 tandis que les éléments clients ont des clés dans la plage -1 ..- 2 ^ 31, il n'y aura donc jamais de collision.

Chaque fois que j'interroge les éléments, je le fais via une vue qui effectue UNION UN entre le contenu des deux tables.

Ainsi, de manière optimale, j'aimerais faire en sorte qu'une clé étrangère fasse référence au résultat de la vue, car la vue sera toujours l'union des deux tables, tout en conservant des ID uniques. Mais je ne peux pas faire cela car je ne peux pas faire référence à une vue.

Maintenant, je peux simplement laisser tomber la clé étrangère et tout va bien. Cependant, j'aimerais vraiment avoir une vérification référentielle et une fonctionnalité de suppression / définition nulle en cascade. Y a-t-il un moyen de le faire, en plus des déclencheurs?

Était-ce utile?

La solution

désolé pour la réponse tardive, un grave cas de week-end m'a frappé.

En ce qui concerne l'utilisation d'une troisième table pour inclure les PC des tables client et système, je n'aime pas cela, car cela complique excessivement la synchronisation et nécessite toujours que mon application connaisse la troisième table.

Un autre problème qui a surgi est que j’ai une troisième table qui doit référencer un élément - système ou client, peu importe. Le fait de séparer les tables signifie en principe que je dois avoir deux colonnes, un ClientItemID et un SystemItemID, chacune ayant une contrainte pour chacune de leurs tables avec une valeur NULL - plutôt moche.

J'ai fini par choisir une solution différente. Le problème était lié à la possibilité de synchroniser facilement les nouveaux éléments du système dans les tables sans toucher aux éléments du client, éviter les collisions, etc.

.

J'ai fini par créer une seule table, Items. Les éléments ont une colonne de bits nommée " SystemItem " cela définit bien l'évident. Dans ma base de données de développement / système, j'ai le PK comme identité int (1,1). Une fois la table créée dans la base de données client, la clé d’identité est remplacée par (-1, -1). Cela signifie que les éléments du client sont négatifs, alors que les éléments du système sont positifs.

Pour les synchronisations, j'ignore fondamentalement quoi que ce soit avec (SystemItem = 1) lors de la synchronisation du reste à l'aide de IDENTITY INSERT ON. Ainsi, je suis capable de synchroniser tout en ignorant complètement les éléments du client et en évitant les collisions. Je suis également en mesure de faire référence à un seul "Articles". table qui couvre les éléments du client et du système. La seule chose à garder à l’esprit est de corriger la clé en cluster standard afin qu’elle décroisse pour éviter tout type de restructuration de page lorsque le client insère de nouveaux éléments (mises à jour du client vs mises à jour du système: 99% / 1%).

Autres conseils

Vous pouvez créer un identifiant unique (db générée - séquence, autoinc, etc.) pour la table référençant les éléments et créer deux colonnes supplémentaires ( tblSystemItemsFK et tblClientItemsFk ). où vous référencez respectivement les éléments système et les éléments client - certaines bases de données vous permettent d’avoir une clé étrangère nullable .

Si vous utilisez un ORM, vous pouvez même facilement distinguer les éléments client et les éléments système (vous n'avez ainsi pas besoin d'identifiants négatifs pour éviter le chevauchement d'identifiant) en fonction des informations de colonne uniquement.

Avec un peu plus de contexte / contexte, il est probablement plus facile de déterminer une solution optimale.

Vous avez probablement besoin d'une table avec les éléments tblItems qui stockent simplement toutes les clés primaires des deux tables. L’insertion d’éléments nécessite deux étapes pour garantir que, lorsqu’un élément est entré dans la table tblSystemItems, la PC est entrée dans la table tblItems.

La troisième table a alors un FK à tblItems. D'une certaine manière, tblItems est un parent des tables des deux autres éléments. Pour interroger un élément, il serait nécessaire de créer un JOIN entre tblItems, tblSystemItems et tblClientItems.

[EDIT-pour le commentaire ci-dessous] Si les tblSystemItems et tblClientItems contrôlent leur propre PK, vous pouvez toujours les laisser. Vous inséreriez probablement dans tblSystemItems d'abord, puis dans tblItems. Lorsque vous implémentez une structure d'héritage à l'aide d'un outil comme Hibernate, vous obtenez un résultat similaire.

Ajoutez une table appelée Items avec un PK ItemiD, et une seule colonne appelée ItemType = " System " ou " Client " puis avoir la table ClientItems PK (nommée ClientItemId) et SystemItems PK (nommée SystemItemId) toutes deux également être FK en Items.ItemId, (Ces relations sont nulles (0-1)

Ensuite, dans votre troisième table qui référence un élément, il suffit que sa contrainte FK fasse référence à l'itemId de cette table supplémentaire (Articles) ...

Si vous utilisez des procédures stockées pour implémenter des insertions, il suffit que le processus stocké insère un nouvel enregistrement dans la table Items en premier, puis, en utilisant la valeur PK générée automatiquement dans cette table, insère l'enregistrement de données dans soit SystemItems, soit ClientItems (selon ce qu’il est) dans le même appel de procédure stocké, en utilisant la valeur générée automatiquement (identité) que le système a insérée dans la colonne ItemId de la table Items.

Cela s'appelle "SubClassing"

J'ai été perplexe sur la conception de votre table. Je ne suis pas certain que c'est juste. Je me rends compte que la troisième table fournit peut-être simplement des informations détaillées, mais je ne peux m'empêcher de penser que la clé primaire est en réalité celle de votre table ITEM et que les clés FOREIGN sont celles de vos tables d'éléments système et client. Il vous suffira ensuite de faire les jointures externes entre les éléments et les tables des éléments système et client, et toutes les contraintes fonctionneront correctement.

J'ai une situation similaire dans une base de données que j'utilise. J'ai une " clé candidate " sur chaque table que j'appelle EntityID. Ensuite, si une table doit faire référence à des éléments de plusieurs autres tables, j'utilise EntityID pour faire référence à cette ligne. J'ai une table Entity qui référence tout (de sorte que EntityID est la clé primaire de la table Entity et que tous les autres EntityID sont des FK), mais je ne me retrouve pas souvent à utiliser la table Entity.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top