vendredi 17 octobre 2008

SQL Server Training (Jour 3) - Intégrité et Trigger

Voila, je vais vite profiter d'une petite pause pour publier le résumé d'avant hier.
Je commence vraiment à crouler sous l'information :-)

Intégrité des données
Aujourd'hui cours sur la gestion de l'intégrité dans les DB.
Il y a trois façons de gérer l'intégrité:
  1. Domain Integrity: Contrainte sur les colonnes, restreindre les valeurs dans le colonnes.
  2. Entity Integrity: intégrité des enregistrements. Chaque record doit être identifié de façon unique (utilisation de Primary Key)
  3. Referential Integrity: L'information contenue dans une colonne doit correspondre au contenu d'une clé primaire d'une autre table.
Options pour renforcer l'intégrité des données:
  • Data types.
  • Rules:  utilisé pour définir les valeurs acceptables dans une colonne. (OBSOLETE, not Ansi compliant).
  • Default Values: permet de définir la valeur par défaut de certains champs. (OBSOLETE, not Ansi compliant).
  • Xml Schema: Permet de renforcer la validation des données dans les champs XML.
  • Triggers: Permet l'execution de code au moment de la sauvegarde/mise-à-jour/effacement d'enregistrement. Les triggers permettent un controle poussé de l'intégrité et du flux de donnée.
  • Constraints: Ansi compliant. Definit comment la moteur DB doit renforcer l'intégrité des données.
    Il existe plusieurs type de contraintes:

    1. Primary Key
    2. Default
    3. Check
    4. Unique - La valeur contenue dans la colonne (ou combinaison de colonnes) doit être unique pour toute la table.
    5. Foreign Key  
Limite des contraintes:
  1. Ne peut pas extraire des données depuis une autre table.
  2. Ne peut pas faire appel à une stored procedure.
Check Constraint
Cette contraite permet de faire des vérifications sur les données (sur base d'expression) lorsqu'elles sont modifiées.
Cette contrainte est l'une des plus mal estimée alors qu'elle est la plus simple et fournit l'une des plus grande valeur ajoutée.
Plusieurs Check Constraint peuvent exister sur un même champ.
Un Check Constraint peut faire référence à un autre champs de la table (mais pas à une autre table).
Les "Check Constraint" ne peuvent pas contenir de sous query (voir Trigger).
Avantages:
Permet la modification d'information depuis une application tiers (Access) ou l'administrateur (SQL Statement) sans mettre l'intégrité des données en danger.
Note:
Il est possible de désactiver des "Check Constraint" pour accélérer le traitement de longues opérations (update, reload).

Foreign Key Constraint
Cette contrainte permet de s'assurer que la valeur d'une colonne correspond bien au contenu de la clé primaire (unique) d'une autre table.
C'est une contrainte d'intégrité référentielle.
Pour un champs soumis à une foreign key, il est impossible d'y introduire une valeur illégale. Bien que protégeant bien l'intégrité des données, les Foreign Keys présentent quelques désavantages les rendant peu populaire.
C'est ainsi que beaucoup de sociétés préfère ne pas implémenter ce genre de contraintes en production (leur préférant les triggers).
Actions:
Lors de la définition des "Foreign Key" constrainte, il est possible de préciser une clause CASCADE (update or delete). Cette dernière clause permet d'indiquer quel operation doit être exécuté sur le record lorsque la référence est modifiée ou effacée.
Par default, l'action est NO ACTION dans les deux cas.
Il est possible d'utiliser CASCADE qui est vraiment dangereux lors de l'effacement de la référence car il efface également les dependences.
Si orderDetails.ProductID reference la table product avec DELETE Cascade, alors l'effacement d'un produit efface également toutes rows orderDetails (where orderDetails.ProductID=product.productID). OUPS!
Il existe également des options SET NULL ou SET DEFAULT (voir 5-21). 

Désavantages:
  • Limite les operations de modification de schéma (renommer des colonnes).
  • Consomme des ressources (il faut faire un choix entre performance et sécurité).
  • Peut se montrer lents lors que la clé primaire de référence appartient à une table très grande.
  • Nécessaire de désactiver ce type de contrainte lors du rebuild des indexes.
  • Représente des contraintes d'utilisation vraiment excessives pour les DB de reporting. Il est en effet courant d'effacer et de recharger de nouvelles données en masse dans ce genre de DB. Dans ce cas, les foreign key représentent des contraintes non nécessaire puisqu'il n'est pas possible de tronquer la table... et la mise à jour d'information en masse est fortement ralentie par la vérification de la contrainte.

Default Constraint
Vraiment utile pour s'assurer que certains champs soient tooujours correctement initialisés.
Sont utilisation est recommandée. 

Triggers
Les triggers permettent d'activer du code (actions) lors d'un événement d'insertion/update/delete de records sur une table.
Le trigger est appelé une seule fois par opération (quelque soit le scope de l'opération). Qu'une requête sql modifie ou efface 1 ou 2000 enregistrements (en fonction de sa where clause), le trigger ne sera activé qu'une seule fois pour la modification entière.
Les triggers sont toujours executés dans la même transaction que l'événement.
Il est par conséquent possible de faire un rollback pour annuler l'événement d'origine.
Mais en contre partie, il faut veiller à avoir un trigger aussi court que possible afin de limiter le temps de transaction.

Il y a deux type de triggers:
  1. After Trigger: Trigger qui sont exécutés après l'événement sur la table. Ce qui permet par exemple de vérifier des contraintes d'intégrité ou de maintenir des tables d'audit. 
  2. Instead Of Trigger: Trigger qui remplace l'événement. Ce qui permet de modifier le comportement standard de SQL Server. Eg: remplacer un effacement physique par un effacement logique ou encore répartir l'information au sauvegarder entre plusieurs tables (utile lorsque le trigger est placé sur une vue).
Recommandation d'usage:

  1. Récuperer les records insérés ou mis-à-jour depuis la table virtuelle "udpated".
  2. Récuperer les records effacés depuis la table virtuelle "deleted".
  3. Le trigger doit être écrit de façon fonctionner avec une table deleted et updated contenant plusieurs enregistrement (erreur courante).
  4. En cas d'effacement, toujours faire un count(*) from deteled pour s'assurer qu'il y a des informations à effacer.
  5. Par default, un trigger n'est pas récursif sur sa propre table.
  6. Un trigger peut déclencher un trigger sur un autre table (cascading firing)

Informations diverses:
  • Pour tester si un champ a été modifié, utiliser la fonction Update(FieldName)
  • Pour stopper une trigger (rollback), utilser RaiseError( N'Message', 10, 1 )
  • Lorsqu'un trigger insert des records dans une autre table, utiliser le mot clé OUTPUT pour récupérer les valeurs des champs identity dans une variable de type table (voir autre article à venir)

Cas d'utilisations:
  • Effectuer un effacement logique (active=0) lors d'une instruction DELETE FROM.
  • Eviter les effacements physique en les interdisants. Meme si la sécurité est mal configuré, il ne sera pas possible d'effacer les records.
  • Propagation d'état. Par exemple, la désactivation d'une catégorie de produit peut egalement désactiver tous les produits et ajouter un commentaire aux commandes en cours sur ces produits.
  • Permettre d'effectuer des vérifications complexes et de retourner des messages d'erreurs préçis.
  • Remplacement de Foreign Key constraint... car les trigger peuvent être désactivés et réactivé pour accélérer des opérations de maintenance. La contrainte d'intégrité implémenté dans le trigger ne sera revérifiée que lors d'une nouvelle modification de l'enregistrement.

jeudi 16 octobre 2008

SQL Server Training - Migration et compatility Level

Durant mon training, j'ai eu l'occasion de mettre la main sur une série de script de diagnostique SQL2005 plus que très intéressant (missing indexes, Index Fragmentation, Index usage, etc).
Ces scripts sont, bien évidement, exécutés depuis une console TSQL et fonctionnent comme attendu.

Par contre, certains d'entre-eux ne fonctionnaient absolument pas la DB de TrialXS.
Vraiment étrange si l'on sait que ces scripts n'analyse que des données système.


La réponse est simple... La DB TrialXS est restaurée depuis un backup SQL2000.
Par conséquent, le compatibility mode "SQL 2000" est appliqué à la DB (voir DB Options) sour SQL2005.
En modifiant le "compatibility mode" j'ai enfin réussit à tester mes merveilleux scripts.

Par contre cela lève une nouvelle question: 
Comment nos applications ISAPI (ou script de migration DB) vont-ils réagir en se connectant sur une même DB configurée en compatibility mode SQL7 (prod actuel) ou SQL2000 (ancien env. développement) ou SQL2005 (actuellement non activé)?


Pour des raisons évidentes de facilités de maintenance (à venir... mais avec les super trainings scripts SQL), les "compatibility mode" des DB de production doivent être configurés SQL2005.

mercredi 15 octobre 2008

SQL Server Training (Jour 2)

Que retenir de cette deuxième journée:

XML
Maintenant que SQL Serveur dispose d'un datatype natif XML, il est possible:
  1. De stocker du contenu XML dans un champs et d'y appliquer des méthodes de traitement spécifiques (XQuery).
  2. De générer directement du contenu XML depuis une requête SQL (FOR XML).
  3. D'accepter un input XML, de le parser et le transformer en données relationnelles (OPEN XML).
Ce chapitre fut relativement intéressant. Surtout concernant la génération de document XML directement depuis des requêtes sql.
Dans ce dernier cas, si l'output n'est pas trop conséquent, cela peut vraiment présenter un avantage. Dans le cas contraire, la mémoire cache et Execution Plan Cache seront pénalisés afins de pouvoir générer le document.
L'intégration de XQuery permet de faire des requêtes vraiment puissantes mixant traitement XML (sur du contenu XML d'un champ) et datatype SQL. Cependant, cela nécessite un parsing des documents XML row par row... ce qui est vraiment très pénalisant pour un moteur de DB.
A noter que la mise en place d'index XML primaire et secondaire (FOR PATH) permettent de réduire le temps de processing XML de façon significatif (D'un coût de 266 à 0.1).
Finallement, d'un avis tout personnel, je ne suis pas certain qu'il soit intelligent de stocker du contenu XML dans une DB en vue d'un traitement quelconque (surtout s'il est récurrent).
L'intégration de contenu XML n'est pas en concordance avec l'aspect d'exploitation relationnel de l'information. Par ailleurs, durant le training, nous n'avons pas fait la référence à un cas existant (même sur demande).

Définition des indexes
Nous avons également eu l'occasion de nous consacrer sur la gestion, la création et le l'optimisation des indexes.

Clustered Index:
Index dont les data pages sont stockées dans l'ordre physique de l'index.
L'index cluster est basé sur un arbre B-Tree BALANCE (équilibré autour du noeud root), chaque noeud disposant de relations "sibling" en plus des relations ascendantes et descendantes.
L'introduction d'un nouvel enregistrement dans de tel index est couteux car il faut eventuellement insérer des pages dans l'arbre, modifier les relations entre les différents noeuds... mais surtout garder l'arbre balancé.
L'avantage de cet index, est que SQL server maintien des statistique permettant d'évaluer la pertinance d'une recherche dans l'arbre (au lieu de simplement envisager un table-scan).

Non Clustered Index:
Fonctionne de façon identique au clustered index (B-Tree) A LA DIFFERENCE que les pages sont soit:
  1. Stockées dans la heap
  2. Soit déjà stockée dans un clustered index.
Chaque noeud du "Non Clustered Index" fait une référence à la page de donnée à l'aide d'une clé.

Note 1: Dans la cas d'une table ne disposant pas d'un Clustered Index, les pages sont stockées dans la heap. Il n'y a donc pas d'emplacement prédefinit pour créer de nouvelles les pages de données. Dans ce cas, les insertions sont plus rapides car la nouvelle page de donnée peut être placée arbitrairement.

Note 2: Dans le cas d'une table disposant d'un Clustered Index, pour accéder à l'information depuis un Non Cluster Index, SQL serveur doit faire beaucoup d'opérations en lecture.
A savoir:
  1. La lecture du Non Clustered Index pour récupérer 'identification des pages data (DataPageID)
  2. Parcours de l'arbre B-Tree pour localiser les pages (DataPageIDs) de données dans le Clustered Index. (il faut garder à l'esprit que dans ce cas, le clustered index n'est trié dans le même ordre).
Conditions de selection d'un index
  1. Pertinence de l'index.
    Un index est utilisé par SQL serveur s'il permet d'exclure 95% (au moins) des records de la table (lors d'une selection).
    Pour ce faire, SQL serveur consulte les statistiques d'index qui permettent d'évaluer la pertinance de l'index pour certaine valeur (Si la table contient 10.000 records et que la statistique mentionne un range de 2.500 records pour une selection particulière alors l'index sera rejeter... un table scan sera plus performant ).
    Il est également important de savoir que lors d'index sur plusieurs colonnes, seul les statistiques de la première colonne de l'indexe sont utilisées.
    Par conséquent, la sélection d'un index couvrant plusieurs colonnes ne se fait que sur base de la pertinance de la première colonne de celui-ci.
  2. Couverture de l'index.
  3. Ordre de tri.
  4. Les hints inclus dans les requêtes SQL pour modifier le comportement du moteur DB.
Gestion des indexes

En SQL2005 Enterprise, il est possible de faire des mise-à-jours d'indexes à la'ide de l'option WITH (ONLINE=ON). Cela évite de locker la table durant toute l'opération permattant ainsi aux applications de poursuivre leurs traitement sans interruption. Cette opération consomme néanmoins beaucoup de temps et de ressources.
Il est a noter qu'en SQL2000, le création d'un index place un Lock exclusif sur la table. Il ne faut donc jamais créer d'index sur les DB de production durant les heures de bureau.


En SQL2005, il est possible:
  1. De modifier (ALTER) ou de reconstuire (REBUILD) un index. Sous SQL2000, la seule option est de détruire et recréer l'index.
  2. d'indiquer le nbre maximum de processeur affecté à la modification d'un index. WITH( MAXDOP=3)
  3. Il est possible de definir une granularité de locking plus fine sur les indexes (ALLOW_ROW_LOCKS). Par default le moteur SQL utilise des locks au niveau de la table!!!. 
  4. D'inclure des colonnes dans l'index sans que ces dernières n'interviennent dans l'index lui-même. Cette dernière optimisation permet de tirer parti des index sur colonnes multiples sans en avoir les inconvénients. En général, les colonnes additionnelles sont ajoutées pour retrouver rapidement des information pertinantes depuis l'index sans lecture de data pages complémentaire. Avant SQL2005, ces colonnes faisaient partie intégrante de l'index... par conséquent, toute modification des colonnes complémentaires réclamaient la mise-à-jour des liens internes et une opération de re-balancing... alors même que ces informations ne participent pas activement à l'index... c'était donc des indexes couteux.

    Avec les "Included Columns", la modification des données complémentaires  n'implique pas les opérations de mise à jours de liens internes et de re-balancing.

    Les indexes en SQL2005 sont à ce point plus efficaces qu'il est possible d'éliminer jusqu'à 60% des indexes nécessaires en SQL2000 tout en gardant les mêmes performances

  5. De créer des "Partitionned index" fonctionnant de façon similaire aux tables partitionnées.
  6. D'indexer le contenu de champs XML afin d'améliorer les performances et cout de recherche de façon spectaculaire.
  7. De désactiver/réactiver des indexes lors de l'exécution de gros batch. Cela permet de gagner du temps machine considérable en évitant à SQL server de constamment mettre à jour l'index. Lors de la réactivation de l'index, ce dernier est reconstruit.
Optimisation des indexes

Database Engine Tuning Advisor:
Cet outil de Microsoft est maintenant bien peaufiner et est un incontournable pour l'optimisation des indexes.
Afin d'effectuer une évaluation des indexes, le Database Engine Tuning Advisor utilise une série de requêtes SQL sensées représenter les cas d'utilisations pratique de la base de données. Ces informations peuvent être fournie depuis un fichier SQL, XML ou une trace collectée à l'aide du profiler SQL.
Malheureusement, ce cas de figure peut difficilement s'appliquer aux DB de production.

Exploiter les statistiques des DB:
Pour les DB de production, il faut savoir que SQL Serveur maintien des vues dynamiques reprenant les statistiques d'usage des différents indexes (dm_db_index_usage_stats).
Par ailleurs, le processus de plannification d'execution tiens des statistiques utiles à propos des indexes idéals répondant à certaines requêtes (dm_db_missing_index_details). Cette vue est utilisée par SQL Serveur lui-même pour éviter certaines conception de plan d'exécution inutiles.
Ces informations peuvent être exploitées avec IndexTuning.sql faisant des jointures sur sys.Indexes pour obtenir de précieux conseils... même en production.
From the result of indexTuning.sql, high cumulated_cost_reduction must be addressed!

Fragmentation des indexes:
Il existe deux types de fragmentations.
La fragmentation interne est due à SQL server lui même et nous ne pouvons rien y faire. Elle a d'ailleurs peu d'influence.
Par contre, la Fragmentation externe correspond à la distribution des pages de données sur le disque (espaces disques alloués par le système d'exploitation).
L'identification de la fragmentation se fait à l'aide de Fragmentation.sql (fichier de démonstration du module 4).
Pour une fragmentation inférieure à 30%, un simple ALTER INDEX ... REORGANIZE est suffisant.
Par contre, pour une fragmentation supérieur à 30% un ALTER INDEX.... REBUILD est absolument nécessaire. Cette dernière opération (couteuse) demande au système d'exploitation d'allouer un espace continu.

SQL Server Training (Jour 1)

Petite semaine de cours intensif en SQL Server 2005 chez U2U.
Au programme, le cours "Implementing a Microsoft SQL Server 2005 Database".
Le cours est très interessant, même pour un développeur expérimenté.
Il y a déjà a tellement raconter que je ne prendrais pas le temps de me relire avant la publication (soyez donc indulgents).
Que retenir de cette première journée:

OLAP et OLTP
Les bases de données peuvent être exploitées pour des applications OLTP (Online Transaction Processing) ou OLAP (Online Analytic Processing).
En fonctionnement OLTP les operations sont optimisées pour le traitement sécurisé d'un grand nombre de transactions.
OLTP met en place les systèmes de locking utilisés de façon intensives afin d'assurer l'intégrité des transactions.
C'est typiquement le cas des systèmes marchands ou des données sont fréquements ajoutées et/ou modifiées.
Les opérations sur une base de données OLTP sont généralement très courtes mais nécessite une grande réactivité.

Par contre, il est également possible d'exploiter une base de donnée en OLAP (Online Analytic Processing).
Le but de ce mode d'exploitation des informations est de fournir des réponses rapidement.
OLAP est indiqué pour la génération de rapports ou de longues requêtes brassent beaucoup d'informations.

Une erreur commune est de faire du reporting sur des bases de données OLTP.
En effet, les rapports executent des query qui prennent beaucoup de temps tout en maintenant des locks en lectures très étendus.
Le reporting n'est donc pas une opération à prévoir sur des bases de données de production au risque de bloquer (ou ralentir significativement) le traitement des transactions.
Pour éviter ce problème, il faut considérer:
  1. Le miroring / DBRestore sur serveur de reporting.
  2. La réplication
  3. Le database snapshot.
Database Snapshot
Le database snapshot est une operation (disponible uniquement sur l'édition enterprise) permettant de faire une copie quasi instantanée d'une DB (même pour une DB de 8 Go).
Ce processus est relativement léger car il ne copie pas "vraiment" la DB de production. Au contraire, lorsque la DB de production est mise-à-jour, seule les  pages modifiées sont copiées (avant modification) dans la DB Snapshot (Copy-On-Write).
Une base de donnée Snapshot est read-only et n'a donc pas besoin de gérer des locks. Les DB Snapshots sont donc des victimes idéales pour des processus de reporting.

Modèle de gestion du Log file
Le modèle "Simple" fait une troncation du Log File dès que possible (idéal pour les environnement de développements).
Le modèle "Full" enregistre de nombreuses informations de transactions dans le transaction Log. Cela permet en autre de garantir un rollback ou restauration de DB a presque n'importe quel point dans le temps.
Ce modèle représente un grand désavantage losrque de larges opérations bulk-insert (insertion de records en lot) ou d'effacement de records prennent places.
En effet, dans ce cas, le log file est littéralement congestionné et grandit rapidement.
Le nouveau model "Bulk-Logged" est un équivalent du mode "full" ou l'enregistrement des opérations dans le log sont sommaire lors d'operations bulk. Dans ce cas, il ne sera possible de restorer l'état de la DB que juste avant (ou juste après) de telles opérations.

Checksum et Torn Page Detection
SQL serveur ne fait pas confiance au disque dur lorsque les informations sont écrites. Les erreurs d'écritures ne sont généralement pas détectée durant cette opération. Le disque dur, peut même ne pas savoir que l'information écrite n'est pas correcte si l'information est corrompue en amont par le matériel.
Pour s'assurer de la fiabilité des informations, SQL server stocke un checksum pour chaque data page. Lors de la lecture le checksum est comparé à celui recalculé sur la page chargée, les données sont corrompues s'ils ne correspondent pas.

Lors d'une migration depuis SQL 7, il est important de savoir que la vérification par checksum n'est pas activée. L'ancienne méthode de vérification (TORN_PAGE_DETECTION) est toujours active même si elle est moins fiable.

Type de donnée
Voici quelques précision relatif au nouveaux types de données (et certains types déjà connus).
Table: Les tables (ou RowSet) sont aussi des types de données. Il est possible de faire des query sur le résultat d'un ou plusieurs autres query.
GUID: Le type GUID permet d'assigner une valeur GUID réputée unique (worldwide unique value).
La fonction sql newGuid() permet d'obtenir un nouvel GUID.
Ce qu'il y a de nouveau, c'est la fonction newSequentialGuid() qui permet de générer des GUID sequentielles... franchement utile lorsque des records doivent être ordonnés.
NVarchar: Utilise 2 bytes pour stocker la longueur de la chaine de caractère.
C'est donc une erreur d'écrire Varchar(1) pour espérer gagner de la place.
TimeStamp: Assigne une valeur unique (dans la DB) au champs lorsqu'un record est ajouté ou modifier. Ce type de donnée est utilisé pour s'assurer que le record n'a pas été modifié depuis la dernière lecture (Ado en fait un usage intensif).
Xml: Permet de stocker nativement du contenu XML. Ce type de donnée permet en autre d'exécuter des methods manipulant l'information. Il est également possible de transformer des données XML en rowset (et inversement).

Schema
Une modification très importante depuis SQL2000 sont les schémas. et représente un virement à 180 degré d'une fonctionalité/syntaxe déja existante (dbo.tablename).
Contrairement à ma première idée, les schémas en SQL2005 n'ont rien à avoir avec les schéma graphique de DB.
Les schemas permettent de regrouper les objects SQL (table, stored proc, etc) de façon logique. C'est un peu comme des groupes ou des domaines.
Les schemas sont définis à l'aide d'instruction appropriée et doivent être référencés dans les divers objects aussi bien lors d'operations de création que d'écritures.
Par exemple, dans le schéma "Person", il serait opportun de créer les tables contactInfo, Address, PersonInfo, Affiliation, etc.
L'identification correct de la table se fait en la préfixant avec le schema adéquat.
Par exemple:
  select * from Person.PersonInfo
Ce qu'il est important de savoir, c'est que l'utilisation les schémas sont obligatoires!!!

L'utilisation des schemas permet en autre de grandement faciliter la gestion de la sécurité... puisque les droits d'accès peuvent être liés au schémas.
Il est aussi utile de noter que chaque utilisateur SQL dispose d'une configuration "default schéma" qui sera automatiquement utilisé pour les requêtes SQL ne précisant pas de schéma.

Attention à la migration des bases de données:
Pour des raisons de compatibilités ascendante, le schéma "dbo" (db owner) existe en SQL 2005 et est maintenu.
Ce dernier, totalement obsolète, ne devrait pas être utilisé pour la création de nouvelles bases de données.
Cependant, le schéma "dbo" existe pour faciliter la migration de DB plus anciennes.
Ainsi, lors d'une migration, les tables sont migrées en utilisant le schéma "dbo".
Lors des requêtes SQL d'anciennes applications (select * from PersonInfo), SQL server essaye d'abord de résoudre le nom de la table dans le "default schema" configuré  pour l'utilisateur. Si ce dernier n'existe pas, alors une tentative est faite sur le schéma "dbo".
Pour les anciennes application n'utilisant pas les schémas dans la notation SQL, il est facile de constater qu'une surcharge de traitement est nécessaire pour obtenir les même données.
Note: En raison de l'utilisation de "dbo", Une assignation arbitraire du "default schema" de l'utilisateur SQL peut avoir des conséquences catastrophiques pour des applications migrées.

Partitioning large table
Lorsqu'une large table content des données devenues "read-only" par l'usage ou tellement vieilles, il convient de partitionner la table (et les indexs liés).
Cela permet à SQL server de focaliser l'activité et usage du cache sur la partition active de la table (nb: les indexes sont partitionnés avec la table).
Le but de la partition est de garder une partie active de taille raisonnable... et donc performante.
Les partitions plus anciennes totalement inactive en écriture peuvent être stockées sur des file group read-only (et peuvent par conséquent être stockés sur des disques compressés) limitant l'implication de locks.
Finalement, la partition à l'avantage de stopper le "lock escalation". Ainsi, la lecture de vieille données n'engendrera pas de read-lock sur la partition active.
Il va de soit que l'accès aux différentes partitions est totalement transparente.

File-Groups et Log File
Il est possible de créer differents File-Group pour y stocker une partie des tables (ou des indexes).
Les file-groups permettent de répartir les tables dans différents fichiers et sur différents disques. Cela permet d'optimiser les performances des tables les plus sollicitées en les placants sur des disques rapides (évitant ainsi de pénaliser les applications transactionelles).
Les file-groups peuvent également êtres marqués comme Read-Only. C'est d'ailleurs conseillé pour les tables (ou partitions de tables) n'étant plus modifiées. Cela permet à Sql Server de ne plus avoir à gérer les locks et permet à l'administrateur de placer le file-group sur un lecteur compressé (seul cas d'utilisation toléré).
Note 2: Le stockage de File-Group read-only sur des lecteurs compressés peut devenir interessant lorsque les parties "inactives" contiennent des millions de records.


Par ailleurs, il est conseilé de stocker le Log file sur un disque séparé (et rapide).
Cela limite la surcharge IO qui devrait être partagé entre le stockage des données et celui du Log File lorsqu'un seul disque est utilisé (Disk Head Overheat situation).

Performances
Pour préserver les performances:
  1. Eviter l'usage de curseur si le code peut être écrit en SQL relationnel. L'exécution des curseurs est jusque 30 fois plus lent.
  2. Eviter l'utilisation des tables temporaires là ou cela est possible. Les tables temporaires ne sont pas optimisée pour la performance et consomment de la mémoire.
  3. Garder le "Page Hit Ratio" a l'oeil. Il indique le nombre de fois que SQL server va directement retrouver l'information nécessaire depuis sa mémoire cache. Si le hit ratio tombe en dessous de 95%, il faut agir.

samedi 11 octobre 2008

Sync Framework

Sync Framework de Microsoft permet de développer plus facilement des fonctionnalités de synchronisation au sein d'applications.
Ce framework permet en autre de faire du caching pour les applications destinées à fonctionner tout aussi bien online qu'offline.
Sync Framework permet de transformer une application locale en application distribuée.
Pour plus d'information, voir les liens ci-dessous.

Liens utiles:
  • Syn Framework sur le site de Microsoft.
    Cette page contient quelques vidéos intéressantes.
  • SyncToy V2.0 est un outil Microsoft utilisant la technologie du Sync Framework.

vendredi 10 octobre 2008

XML Notepad

XML Notepad 2007
XML Notepad est un outil d'édition XML distribué gratuitement par Microsoft.
XML notepad est décrit sur cet article de MSDN.
Simple éditeur XML disponible ici.

Outils XML
Le site MSDN de Microsoft propose aussi d'autres outils ici.
On y trouvera par exemple:
  • XML Diff
  • XML Schema Definition Tool
  • XSD Sample Code Generator (XSDObjectgen)

mercredi 8 octobre 2008

Mono 2.0

Voila que j'apprends que Mono 2.0 vient d'être délivré.
Parmis les plus grandes avancées de cette version, il y a:
  • L'arrivée tant attendue d'un débugger.
  • Le support de C#3.0 avec LINQ to Objects LINQ to XML.
  • Un compilateur Visual Basic 8. 
L'éco-système Mono s'agrandit de plus en plus.
En plus d'être un moteur de script dans Second Life, Mono est également inclus dans des produits tel que des lecteurs MP3 (voir ici l'initiative de SanDisk), sur la console de jeu Nintendo Wii ou encore sur iPhone d'Apple.
Pour encore plus d'application, allez donc visiter cette page reprenant des capture d'écrans d'applications GTK#, WinForm, Asp.Net (et autre) fonctionnant sous Mono.

Moins tape à l'oeil que l'intégration d'un débuggeur, l'environnement Mono 2 débarque avec une série de caractéristique non négligeable. A savoir:
  • Le support d'autres compilateurs:

    • IronPython de Microsoft.
    • Phalanger (PHP fonctionnant sous CLI)
    • IronRuby de Microsoft.
    • Eiffel ISE
    • Microsoft C#, F# et VB.NET
    • RemObject d'Oxygene (Pascal Objet pour .Net qui supporte les Generics, Class Contrcts, Queries, etc)
  • Les API.Net

    • Support du Core 2.0, System.Core (v3.5)
    • System & System.Xml
    • System.Drawing
    • System.Web.Services & System.DirectoryServuces
    • Windows.Forms 2.0 (en utilisant des drivers W32, OSX, X11 unix).
    • ASP.NET 2.0 (Core, Ajax)
    • Intégration Apache et Fast CGI
    • Ado.Net 2.0 pour SQL server mais également pour d'autres base de données.
Enfin, pour les vraiment curieux, il y a des APIs et greffons spécifiques à Mono:
  • Mono.Cairo une interface de programmation pour rendu graphique en 2D
  • Mono.Cecil une interface de programmation permettant de charger et manipuler des assemblies binaires.
    Avec Mono.Cecil, il est possible de naviguer dans tous les types d'un assembly, de les modifiers instantanément et sauver l'assembly modifiée sur le disque.
    Mono.Cecil va beaucoup plus loin que  Reflection & Reflection.Emit, c'est grâce à Mono.Cecil que le débugger de MonoDevelop pu être développé.
  • Xml.Relaxng
  • Bit# une librairie client.server Bittorent.
  • Mono.Fuse pour manipuler des systèmes de fichiers dans l'espace utilisateur.
  • Tao Framework - OpenGL, OpenAL, SDL and Cg
Pour finir, voici quelques liens:


Note 1: Concernant l'intégration de Mono dans l'iPhone et la Wii, cette intégration se fait via le moteur de jeu Unity 3D lui même basé sur Mono. Un petit coup d'oeil sur Unity 3D ne vous laissera pas de glace.
Note 2:  Cette nouvelle release de mono est également l'occasion de prendre connaissance de deux nouveaux environnements de développement .Net sous Unix. Même s'ils sont payant, c'est néanmoins intéressant. Mon article à ce sujet sera donc mis-à-jour.