Contexte
J'écris de nombreux rapports volumineux et je gère généralement une grande base de données de dossiers de santé (écriture de SP, fonctions, travaux, etc.). Le schéma d'origine et le logiciel qui l'utilise proviennent d'un fournisseur différent, donc je ne peux pas y changer grand-chose structurellement. Il existe de nombreux enregistrements qui nécessitent un suivi tels que les laboratoires, les procédures, les vaccins, etc. et ils sont dispersés sur des dizaines de tableaux, dont beaucoup sont gonflés et mal indexés (j'ai pu résoudre ce problème quelque peu).
Le problème
Le problème est que, parce que nous avons peu de contrôle sur la base de données et qu'elle peut changer à partir d'une mise à jour ou d'un correctif donné, cela rend la rédaction et la maintenance de ces rapports difficiles et fastidieuses, en particulier en cas de chevauchement important. Tout ce qu'il faut, c'est un patch et je suis coincé à réécrire de grandes parties d'une douzaine de rapports. De plus, les requêtes deviennent rapidement obscurcies et lentes à mesure que les jointures, les sélections imbriquées et les applications s'empilent.
Ma "solution"
Mon plan consistait à écrire tous ces enregistrements dans une table «fourre-tout» et à écrire des déclencheurs sur les tables d'origine pour conserver les enregistrements dans cette table agrégée. Bien sûr, je devrais m'assurer que mes déclencheurs étaient intacts après les mises à jour, mais cela serait beaucoup plus facile du point de vue de la maintenabilité et du simple référencement des données.
Le tableau serait mince et long, ne stockant que les données requises, quelque chose comme ceci:
CREATE TABLE dbo.HCM_Event_Log (
id INT IDENTITY,
type_id INT NULL,
orig_id VARCHAR(36) NULL,
patient_id UNIQUEIDENTIFIER NOT NULL,
visit_id UNIQUEIDENTIFIER NULL,
lookup_id VARCHAR(50) NULL,
status VARCHAR(15) NULL,
ordered_datetime DATETIME NULL,
completed_datetime DATETIME NULL,
CONSTRAINT PK_HCM_Event_Log PRIMARY KEY CLUSTERED (id)
)
Ensuite, j'aurais diverses tables relationnelles pour des choses comme les groupements type_id et item.
Je commence à deviner cette idée, car plusieurs de ces tableaux sont écrits dans une certaine mesure, les SP et les rapports que j'écrirais feraient également référence aux données. Je crains donc que cette table ne devienne un cauchemar de verrouillage et de performances avec autant d'E / S.
Ma question
Est-ce une mauvaise ou une bonne idée? Je me rends compte que chaque situation est différente dans SQL Server (2008 r2 Standard Edition BTW), et la règle «parfois», mais je suis vraiment à la recherche de conseils généraux.
J'ai commencé à envisager d'utiliser un courtier de services, mais je n'effectuerais que de simples mises à jour / insertions ( voir l'alternative à la réponse acceptée ). Dans de nombreux cas, les données doivent être en temps réel, donc l'utilisation d'une base de données de sauvegarde ne fonctionnerait pas vraiment. Les performances sont déjà quelque peu un problème pour nous, mais la plupart d'entre elles sont liées au matériel et seront bientôt résolues.
la source
Réponses:
Si je vous ai bien compris,
Je l'approcherais comme ceci:
Dans ce cas, vous pouvez affiner la structure et les index de votre base de données pour améliorer les performances de vos rapports, sans affecter le système tiers. À moins que la structure de données d'origine ne change radicalement, la logique de vos requêtes pour vos rapports ne changera pas si la base de données tierce change. Vous ne devriez ajuster que le processus de synchronisation.
Le processus de synchronisation est en fait le processus de conversion - vous convertissez les données d'une base de données tierce en la structure dont vous avez besoin. Une partie de ce processus de conversion pourrait résoudre les problèmes de normalisation que la base de données tierce d'origine pourrait avoir. Seule cette partie du système doit connaître et dépendre de la structure interne du système tiers. Vos principaux rapports et requêtes principales ne dépendraient que de votre base de données.
Donc, le point principal est - séparez et limitez la partie de votre système qui dépend des internes du système tiers.
mise à jour
Concernant l'exigence en temps réel. BTW, j'ai toujours pensé que la définition de "temps réel" est "temps de réponse garanti", pas "un petit temps de réponse". Cela dépend bien sûr de votre application. Dans ma pratique, il suffit que je synchronise deux bases de données dans la minute suivant le changement détecté. Si un utilisateur voit un rapport à l'écran et certaines modifications de données sous-jacentes, le rapport doit être réexécuté pour refléter cette modification. Vous pouvez interroger les modifications ou écouter certains événements / messages, mais la requête de rapport doit être exécutée à nouveau pour afficher les dernières modifications.
Vous avez déjà l'intention d'écrire des déclencheurs pour capturer les modifications dans les tables d'origine et d'écrire ces modifications dans une table générique. Donc, capturez les modifications comme vous le vouliez, mais écrivez-les dans des tableaux correctement normalisés, pas un seul.
C'est donc un cas extrême - la conversion de la structure de données tierce en votre structure de données interne est effectuée dans les déclencheurs qui se déclenchent sur
INSERT/UPDATE/DELETE
des tables tierces. Cela peut être délicat. Le code des déclencheurs dépendrait de la structure interne des deux systèmes. Si la conversion n'est pas anodine, elle peut retarder l'originalINSERT/UPDATE/DELETE
au point de l'échouer. S'il y a un bug dans votre déclencheur, il peut affecter la transaction d'origine au point de l'échec. Si un système tiers change, cela peut casser votre déclencheur, ce qui entraînerait l'échec des transactions du système tiers.Cas moins extrême. Pour rendre le code de vos déclencheurs plus simple et moins sujet aux erreurs, écrivez toutes les modifications capturées dans certaines tables de staging / audit / diff, définissez un indicateur / envoyez un message indiquant que des modifications sont en attente et lancez le processus de conversion principal qui irait à travers ces tables intermédiaires et effectuer la conversion. L'essentiel ici est que le processus de conversion potentiellement lourd devrait se produire en dehors de la portée de la transaction d'origine.
À un deuxième coup d'œil, cela ressemble à peu près à votre suggestion d'origine dans la question. Mais la différence est la suivante: les tables de capture globale contiennent uniquement des données temporairement; la quantité de données est petite - juste ce qui a changé; il n'est pas nécessaire que ce soit une seule table; éventuellement, les données seront stockées dans des tables permanentes distinctes correctement normalisées, dont vous avez le plein contrôle, qui sont indépendantes du système tiers et que vous pouvez régler pour vos requêtes.
la source
Dans tous les cas, placez-le dans un ensemble normalisé de tableaux afin de pouvoir modifier l'étape d'importation plutôt que de devoir modifier des rapports et des requêtes complexes. Mais les données devraient encore être normalisées, ce qui nécessitera plusieurs tables (mais avec de bons indices).
Comme d'autres l'ont mentionné, n'utilisez pas de déclencheurs, synchronisez par lots.
Ne vous inquiétez pas de nombreuses jointures, lorsque les données sont normalisées et indexées correctement, celles-ci n'ajoutent pas de coût ni de charge de gestion importants.
Le moment de se dénormaliser en quelque chose comme un entrepôt de données, c'est quand vous devez être en mesure de faire beaucoup de différents types de requêtes sur les données que vous ne pouvez pas prédire. Il a ses propres inconvénients et frais généraux et devrait être utilisé le cas échéant, et non comme une chose de choix.
la source
J'ai travaillé avec une situation très similaire comme celle-ci dans le passé dans une entreprise de fabrication 24h / 24 et 7j / 7 et j'ai finalement décidé d'utiliser la réplication transactionnelle. Il est possible de configurer DDL pour qu'il soit répliqué de sorte que vous puissiez envoyer tout ce que les correctifs changeront à l'abonné. De toute évidence, il y a des avantages et des inconvénients à tout et vous devez les peser pour déterminer ce que vous pouvez soutenir par rapport à ce qui fonctionne le mieux pour l'entreprise.
Du côté positif:
Il y a cependant des inconvénients:
la source
Les déclencheurs ont tellement de problèmes que vous devriez les éviter:
Une meilleure option est un travail qui copie périodiquement les données dans une nouvelle table. Vos rapports peuvent exécuter la copie. Un travail qui copie des lignes est facile à écrire et à gérer, et il n'y a aucun risque qu'il affecte le fonctionnement de l'application tierce.
la source
NOCOUNT
? 4. Il n'y aurait pas de déclencheurs sur la table de destination, et je pourrais garantir la même chose pour les autres.