Actuellement, nous avons une base de données et une application existantes qui sont entièrement fonctionnelles. Je n'ai pas la possibilité de changer l'architecture à ce stade. Aujourd'hui, chaque table de la base de données possède un champ "IsDeleted" NOT NULL BIT avec une valeur par défaut de "0". Lorsque l'application «supprime» les données, elle met simplement à jour l'indicateur IsDeleted à 1.
Ce que j'ai du mal à comprendre, c'est comment les index de chacune des tables doivent être structurés. À l'heure actuelle, chaque requête / jointure / etc implémente toujours la vérification IsDeleted. C'est une norme que nos développeurs doivent suivre. Cela étant dit, j'essaie de déterminer si tous mes index de clé primaire en cluster sur chacune des tables doivent être modifiés pour inclure la clé primaire ET le champ IsDeleted BIT. De plus, puisque CHAQUE requête / jointure / etc. doit implémenter la vérification IsDeleted, est-ce une hypothèse appropriée que CHAQUE index SINGLE (non cluster également) devrait inclure le champ IsDeleted comme premier champ de l'index?
Une autre question que je me pose concerne les index filtrés. Je comprends que je pourrais mettre des filtres sur les index tels que "WHERE IsDeleted = 0" pour réduire la taille des index. Cependant, comme chaque jointure / requête devra implémenter la vérification IsDeleted, cela empêcherait-il l'utilisation de l'index filtré (puisque la colonne IsDeleted est utilisée dans la jointure / requête)?
N'oubliez pas que je n'ai pas la possibilité de modifier l'approche IsDeleted.
la source
IsDeleted
colonne, quel que soit le stockage physique, il serait probablement judicieux d'exposer les données à travers deux vues (éventuellement dans des schémas différents), résolvant à la fois le problème de paramétrage et faisant des erreurs avec l'accès aux données qui n'auraient pas dû être accès moins probable. L'accès aux données de base n'est pertinent que dans les rares cas où les données supprimées et non supprimées doivent être combinées d'une manière ou d'une autre, et lorsque les lignes doivent réellement être commutées sur "supprimées".C'est peut-être une opinion impopulaire, mais je ne pense pas qu'il y ait une réponse "à faire partout" / taille unique à votre question.
Si vous avez des requêtes qui analysent de nombreuses lignes IsDeleted sans raison, une solution consiste à créer un index filtré et non cluster pour satisfaire cette requête.
Une autre option consiste à créer une vue indexée qui pourrait être exploitée par un certain nombre de requêtes différentes, qui est filtrée uniquement sur les lignes non supprimées. Cela pourrait être particulièrement utile sur Enterprise Edition, où la correspondance automatique des vues indexées fonctionne sans fournir d'
NOEXPAND
indice.Pour les petites tables, ou les tables qui sont lues intensivement, l'ajout d'index ou de vues non clusterisés filtrés ou quoi que ce soit pourrait vraiment simplement ajouter une surcharge inutile à votre base de données.
la source
Dans l'hypothèse raisonnable que les suppressions sont rares, aucune modification des indices n'est une solution appropriée.
J'ai constaté que tôt ou tard, il faut rechercher des références aux lignes supprimées, et les lignes se trouvant dans les index en valent soudainement la peine.
Veuillez noter qu'à moins que vous n'utilisiez des vues, vous devez de toute façon modifier toutes vos requêtes pour inclure les filtres.
la source
J'ai vu un système où le drapeau IS_DELETED est 0 ou la valeur du PK. Dans d'autres systèmes, c'était le négatif du PK.
Étant donné que la plupart des requêtes ont récupéré des valeurs par la clé "naturelle" ou commerciale (parfois multi-champs), elles n'ont jamais interrogé PK sauf par le biais de jointures; mais ils ont toujours ajouté un AND IS_DELETED = 0 à la fin pour la table principale et pour toutes les tables jointes.
Ce système avait également une table d'audit pour chaque table transactionnelle qui suivait les changements; et l'application avait une fonctionnalité pour afficher toutes les modifications de données, y compris les données supprimées.
la source
J'espère que vous avez le droit et la possibilité de modifier la requête.
Je voulais dire un point important, j'espère pouvoir l'expliquer.
Dans une requête complexe, où
Transaction table
etMaster
tables sont utilisés.Utiliser
IsDeleted=0
uniquement dans leTransaction
tableau. Ne pas utiliser dans leMaster
tableau.Exemple,
Cela ne sert à rien
c.isdeleted=0
(d'utiliser dans leCategory
tableau), c'est inutile.De même, est-il utile d'utiliser
P.isdeleted=0
?Parce que je veux tous les Ordres non supprimés et leurs détails.
Comment peut
Product
être supprimé quandOrder
estActive
ou oùProductid
est la référence.Donc, de cette façon, si vous déboguez soigneusement dans une requête importante, vous pouvez supprimer certains isdeleted = 0.
Ne créez pas aveuglément un index filtré, sélectionnez d'abord toutes ces requêtes très importantes et lentes.
Optimisez ces requêtes lentes, puis décidez uniquement de l'index filtré ou de l'index de réglage.
la source