TSQL les clés étrangères des points de vue?
J'ai un SQL-Server 2008 de la base de données et un schéma qui utilise les contraintes de clé étrangère pour appliquer l'intégrité référentielle. Il fonctionne comme prévu. Maintenant, l'utilisateur crée des vues sur les tables d'origine pour travailler sur des sous-ensembles de données uniquement. Mon problème est que le filtrage de certains jeux de données, dans certains tableaux, mais pas dans d'autres, ne pas violer les contraintes de clé étrangère.
Imaginez deux tables "un" et "deux". "une" contient juste une id de la colonne avec les valeurs 1,2,3. "Deux" références "un". Maintenant, vous créez des vues sur les deux tableaux. La vue de la table de "deux" ne filtre pas quelque chose pendant que l'affichage de la table "on" supprime toutes les lignes, mais le premier. Vous vous retrouverez avec des entrées dans le second point de vue que le point de nulle part.
Est-il un moyen pour éviter cela? Pouvez-vous avoir les contraintes de clé étrangère entre les points de vue?
Quelques Précisions en réponse à certains commentaires:
Je suis conscient que les contraintes sous-jacentes sera d'assurer l'intégrité des données, même lors de l'insertion à travers les points de vue. Mon problème est avec les déclarations de consommer de la vue. Ces déclarations ont été écrits avec les tables d'origine à l'esprit et à assumer certaines jointures ne peut pas échouer. Cette hypothèse est toujours valable lorsque l'on travaille avec les tables - mais les points de vue potentiellement briser il.
Joindre/vérification de toutes les contraintes lors de la création de la vue, en premier lieu, annyoing en raison du grand nombre de font référence à des tables. J'étais donc dans l'espoir d'éviter que.
- Avez-vous besoin de s'inquiéter à ce sujet? Les clés étrangères d'insertion de contrôle/mise à jour des données, ils ne sont pas vérifiées lors de la sélection.
- Pourquoi ne pas vous filtrez les deux points de vue?
- Pourriez-vous me donner un exemple? Je ne comprends pas comment lire les tableaux peuvent influencer l'intégrité référentielle? Peut-être quelques tables avec des données, les points de vue et le problème que vous avez?
- "certaines jointures ne peut pas fail?" Une jointure jamais "échoue." Si vous effectuez une JOINTURE INTERNE de Vue2 à Vue1 alors le résultat sera le même filtre que Vue1 a. Il fonctionne comme prévu.
- Comme dit Aaron, se joint ne peut pas échouer. Que voulez-vous arriver dans votre application? Voulez-vous les lignes pour ne pas montrer en soit, s'ils en violation de l'une? Voulez-vous que l'utilisateur particulier d'être incapable de créer une ligne qui viole la vue à laquelle ils ont accès?
- Avez-vous envisagé de demander à ask.sqlservercentral.com - qui est un site qui utilise le StackOverflow moteur, mais a un nombre croissant de SQL experts en suspens?
Vous devez vous connecter pour publier un commentaire.
Peter déjà frappé, mais la meilleure solution est de:
I. e.,
Sûr, sucre syntaxique pour la multiplication de filtres pour les points de vue sur une table de points de vue sur les actions subalternes à tables de, ce serait pratique, mais hélas, il ne fait pas partie de la norme SQL. Cela dit, cette solution est encore assez bon -- efficace, simple, facile à maintenir, et des garanties de l'état souhaité pour les consommateurs de code.
J'aime votre question. Il hurle de familiarité avec l'Optimiseur de Requête, et comment il peut voir que certaines jointures sont redondantes si elles ne servent à rien, ou si l'on peut simplifier quelque chose en sachant qu'il y a au plus un coup sur l'autre côté de la jointure.
Ainsi, la grande question est de savoir si vous pouvez faire un FK contre la CIX d'une Vue Indexée. Et la réponse est non.
Tout cela fonctionne sauf pour la dernière instruction, des erreurs avec:
Donc la clé Étrangère doit faire référence à une table utilisateur.
Mais... la prochaine question est de savoir si vous pourriez faire référence à un index unique qui est filtré SQL 2008, pour atteindre un point de vue-comme FK.
Et encore, la réponse est non.
Cela a réussi.
Mais maintenant, si j'essaie de créer une table qui référence les
val
colonne(J'espérais que la vérification de la contrainte qui correspondent au filtre dans l'index filtré peut aider le système à comprendre que le FK devraient l'être)
Mais j'obtiens un message d'erreur disant:
Si je baisse l'index filtré et créer un non-filtré unique index non-cluster, puis je peux créer dbo.thirdtable sans aucun problème.
Alors je crains que la réponse semble être Non.
Il m'a fallu un certain temps pour comprendre le misunderstaning ici -- ne sais pas si j'ai encore totalement compris, mais ici il est.
Je vais utiliser un exemple, près de la vôtre, mais avec quelques données -- plus facile pour moi de penser en ces termes.
Donc d'abord deux tables; A = Département B = Employé
Maintenant, je vais jeter quelques données dans
Donc, maintenant, je vais créer une vue sur la première table de filtrer certains départements.
Cela renvoie
Et par votre exemple, je vais ajouter une vue de la deuxième table qui ne filtre rien.
Cela renvoie
Il me semble que vous pensez que l'Employé N ° 5, DepartmentID = 3 points de nulle part?
Bien, il souligne l'
Department
tableDepartmentID = 3
, tel que spécifié par la clé étrangère. Même si vous essayez de joindre vue sur vue rien n'est cassé:Retourne
Si rien n'est cassé ici, la jointure n'a tout simplement pas trouver la correspondance des enregistrements pour
DepartmentID <> 2
C'est en fait la même que si je les tables de jointure et puis filtre inclure comme dans le premier point de vue:Retourne de nouveau:
Dans les deux cas, les jointures ne manquent pas, ils sont simplement comme prévu.
Maintenant, je vais essayer de briser l'intégrité référentielle par le biais de vue (il n'y a pas de DepartmentID= 127)
Et il en résulte:
Si j'essaie de supprimer un service à travers le point de vue
Qui se traduit par:
Donc les contraintes sur les tables sous-jacentes s'appliquent toujours.
Espère que cette aide, mais alors peut-être que j'ai mal compris votre problème.
Si vous essayez d'insérer, mettre à jour ou supprimer des données par l'intermédiaire d'un point de vue, la table sous-jacente contraintes s'appliquent toujours.
Quelque chose comme cela dans Vue2 est probablement votre meilleur pari:
Si rouler sur les tables afin que les colonnes d'Identité seront pas en conflit, une possibilité serait d'utiliser une table de recherche qui référence les différentes tables de données d'Identité et d'une table de référence.
Clés étrangères sur cette table de travail en bas de la ligne pour le référencement de tables.
Ce serait cher en un certain nombre de façons
L'intégrité référentielle sur la table de recherche devra être exécutée à l'aide de déclencheurs.
De stockage supplémentaire de la table de recherche et d'indexation en plus des tables de données.
La lecture des données serait presque certainement impliquer une Procédure Stockée ou trois pour exécuter une filtré de l'UNION.
Plan de requête d'évaluation aurait également un coût de développement.
La liste est longue, mais il pourrait travailler sur certains scénarios.
À l'aide de Rob Farley schéma:
J'ai dû créer une petite table d'assistance (dbo.z) pour faire ce travail, parce que les vues indexées ne peut pas avoir l'auto-jointures, les jointures externes, sous-requêtes, ou de tables dérivées (et TVCs comptent comme des tables dérivées).
Une autre approche, en fonction de vos besoins, serait d'utiliser une procédure stockée pour retourner les deux jeux d'enregistrements. Vous transmettre des critères de filtrage et il utilise les critères de filtrage pour interroger le tableau 1, et les résultats peuvent être utilisés pour filtrer la requête à la table 2, afin que les résultats sont également cohérents. Ensuite, vous revenez à la fois des résultats.
Vous pourriez stade filtré tableau 1 données d'une autre table. Le contenu de cette mise en scène de la table sont à votre vue 1, puis vous construisez vue 2 via une jointure de la table intermédiaire et le tableau 2. De cette façon, le proccessing pour le filtrage de la table 1 est fait une fois et réutilisés pour les deux points de vue.
Vraiment ce qu'il se résume à ce point de vue 2 n'a aucune idée de quel type de filtrage que vous avez effectué à vue 1), sauf si vous dites à vue 2 les critères de filtrage, ou de les rendre en quelque sorte tributaire des résultats de la vue 1, ce qui signifie que l'émulation de la même filtrage qui se produit sur vue1.
Contraintes de ne pas effectuer tout type de filtrage, elles ne préviennent des données non valides, ou en cascade principales modifications et les suppressions.
Non, vous ne pouvez pas créer des clés étrangères sur les points de vue.
Même si vous le pouviez, que feront-vous? Vous auriez encore de déclarer la FK après la création de la vue. Qui déclare la FK, vous ou l'utilisateur? Si l'utilisateur est suffisamment sophistiqué pour déclarer un FK, pourquoi ne pouvait-il pas ajouter une jointure interne à la vue référencée? par exemple:
vs:
Je ne vois pas comment la clé étrangère de simplifier votre travail.
Sinon:
Copier le sous-ensemble de données dans un autre schéma ou de la base de données. Même les tables, les mêmes touches, moins de données, une analyse plus rapide, moins conflictuel.
Si vous avez besoin d'un sous-ensemble de tous les tableaux, utiliser une autre base de données. Si vous avez besoin seulement d'un sous-ensemble de certains tables, utiliser un schéma dans la même base de données. De cette façon, vos nouvelles tables peuvent toujours référence à la non-copié tables.
Puis utilisez les points de vue de copier les données sur. Tout FK violations génère une erreur et identifier les points de vue nécessitent des modifications. Créer un emploi et le calendrier tous les jours, si nécessaire.
D'une approche purement intégrité des données de point de vue (et rien à voir avec l'Optimiseur de Requête), j'avais envisagé une Vue Indexée. J'ai pensé que vous pourriez faire un index unique, qui pourrait être rompu lorsque vous essayez d'avoir violé l'intégrité dans vos tables sous-jacentes.
Mais... je ne pense pas que vous pouvez contourner les restrictions de vues indexées assez bien.
Par exemple:
Vous ne pouvez pas utiliser les jointures externes, ou des sous-requêtes. Qui rend très difficile de trouver les lignes qui n'existent pas dans la vue. Si vous utilisez des agrégats, vous ne pouvez pas utiliser AVOIR, de sorte que les coupes certaines options vous pouvez utiliser on trop. Vous ne pouvez même pas avoir des constantes dans une vue indexée si vous avez groupement (si vous utilisez une clause GROUP BY), de sorte que vous pouvez même pas essayer de mettre un index sur un champ constant de sorte qu'une seconde ligne va tomber. Vous ne pouvez pas utiliser de l'UNION de TOUS, de sorte que l'idée d'avoir un nombre qui va casser un index unique quand il frappe un second zéro ne fonctionne pas.
Je me sens comme il devrait y avoir une réponse, mais je crains que vous allez avoir à prendre un bon coup d'oeil à votre conception réelle et le travail ce que vous avez vraiment besoin. Peut-être les déclencheurs (et un bon index) sur les tables concernées, ainsi que toutes les modifications qui pourraient casser quelque chose peut rouler tout ça.
Mais j'espérais vraiment être en mesure de proposer quelque chose que l'Optimiseur de Requête peut être en mesure de l'effet de levier pour aider à la performance de votre système, mais je ne pense pas que je peux.