verifier qu’une sauvegarde est bonne.

Le seul moyen de s’assurer qu’une sauvegarde est bonne est d’appliquer la restauration sur une nouvelle base.

nom base initial : test
nom base finale : test2

USE master
GO
SELECT ‘kill’,spid
FROM sysprocesses
WHERE dbid=db_id(‘test2′)
GO
/* Exécution de l’output de la commande ci-dessus afin de libérer la base */
GO
RESTORE DATABASE test2 FROM DISK=N'C:\BACKUP\2007711TEST.bak' WITH
MOVE N’TEST’ TO N’C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\test2.mdf‘,
MOVE N’TEST_log’ TO N’C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Test2_Log.ldf‘, REPLACE
ALTER DATABASE test2 MODIFY FILE (NAME=N’TEST’, NEWNAME=N’test2′)
ALTER DATABASE test2 MODIFY FILE (NAME=N’TEST_log’, NEWNAME=N’test2_log’)
GO

cette technique de restauration en ligne de commande n’est pas tres utilise. Dans l’article suivant, Romelard Fabrice nous explique comment restaurer une base sur une autre à l’aide de sql serveur manager : http://www.technos-sources.com/tutorial.aspx?ID=37

Pour connaitre les processus sur le serveur :
EXEC SP_WHO

choix des tables et colonnes à indexer.

Indexer…
les tables qui ont de nombreuses lignes ( au moins 100 000 ).
les colonnes souvent utilisées dans les requetes.
les colonnes utilisées dans les fonctions d’agregation
les colonnes utilisées dans les requetes group by
les colonnes utilisées dans les requetes order by
les colonnes utilisées dans les jointures, nottament les clef étrangères!

Ne pas indexer…
Les tables qui ont peu de lignes ( moins de 10 000 )
Les colonnes utilisées rarement dans les requêtes
Les colonnes de taille importante
Les colonnes souvent modifiées mais peu interrogées.

FONCTION DE FENETRAGE ET DE RANKING.

Syntaxe :
ROW_NUMBER() OVER([PARTITION BY value_expression ] ORDER BY value_expression)
Définition :
ROW_NUMBER()
Retourne le numéro séquentiel d’une ligne d’une partition d’un jeu de résultats, en commençant à 1 pour la première ligne de chaque partition
PARTITION BY
Divise l’ensemble de résultats en partitions. La fonction de fenêtre est appliquée à chaque partition séparément et le calcul redémarre pour chaque partition.
toute l’information à l’adresse :
http://sqljunkies.com/Article/4E65FA2D-F1FE-4C29-BF4F-543AB384AFBB.scuk

Un exemple d’utilisation :
Fournir les 3 premiers traffic d’un identificateur de cellule par semaine.

CREATE TABLE TRAFFIC_CELLULES(identificateur_de_cellule CHAR(3),traffic INT,date DATETIME);  <br />
 <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('A',100,'01/01/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('A',200,'01/01/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('A',225,'01/01/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('A',400,'01/01/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('A',150,'01/02/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('A',175,'01/02/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('A',200,'01/02/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('B',100,'01/01/2008') <br />
INSERT INTO TRAFFIC_CELLULES(identificateur_de_cellule,traffic,date) VALUES ('B',100,'01/03/2008')  <br />
 <br />
WITH selection <br />
AS <br />
( <br />
SELECT identificateur_de_cellule,traffic,datepart(ww,date) as sem,ROW_NUMBER() OVER (PARTITION BY identificateur_de_cellule,datepart(ww,date) ORDER BY traffic) as OrderRank FROM TRAFFIC_CELLULES <br />
) <br />
SELECT * FROM selection where OrderRank <= 3 <br />
 <br />
Resultat: <br />
 <br />
A      100    1    1 <br />
A      200    1    2 <br />
A      225    1    3 <br />
A      150    5    1 <br />
A      175    5    2 <br />
A      200    5    3 <br />
B      100    1    1 <br />
B      100    9    1

Expression de table courante.

Une expression de table courante ( CTE pour common Table Expression ) ressemble beaucoup à une vue non persistante.

Syntaxe :

WITH nom_CTE ( nom_colonne,… )
AS
(
requete
)
SELECT * FROM nom_CTE

Exemple de code :

WITH selection AS (
SELECT identificateur_de_cellule,traffic,datepart(ww,date) as sem,ROW_NUMBER() OVER (PARTITION BY identificateur_de_cellule,datepart(ww,date) ORDER BY traffic) as OrderRank FROM TRAFFIC_CELLULES
)
SELECT * FROM selection where OrderRank < salespersonid='sp.SalesPersonID'
UNION ALL
selectionner
)
SELECT * FROM simpleRecursive

Exemple :

– Creation d’une table avec les données sous forme d’arbre
CREATE TABLE Employee_Tree( Employee_NM nvarchar(50), employee_ID int Primary Key, reportsTo int )
INSERT INTO Employee_Tree VALUES (‘Richard’,1,NULL)
INSERT INTO Employee_Tree VALUES(‘Stephen’,2,1)
INSERT INTO Employee_Tree VALUES(‘Clemens’,3,2)
INSERT INTO Employee_Tree VALUES(‘Malek’,4,2)
INSERT INTO Employee_Tree VALUES(‘Goksin’,5,4)

–Requete recursive
WITH SimpleRecursive(Employee_NM,Employee_ID,ReportsTo) AS
( SELECT Employee_NM, Employee_ID, ReportsTo FROM Employee_Tree WHERE Employee_ID = 2
UNION ALL
SELECT p.Employee_NM, p.Employee_ID, p.reportsTo FROM Employee_Tree p INNER JOIN SimpleRecursive A ON A.Employee_ID = P.ReportsTo
)
SELECT sr.Employee_NM AS Employee, et.Employee_NM As Boss FROM SimpleRecursive sr INNER JOIN Employee_Tree et ON sr.ReportsTo = et.Employee_ID

lien : http://sqlpro.developpez.com/cours/sqlserver/cte-recursives/

Récursivité, CTE et génération de table.

Bonjour,

Samedi, en me promenant sur le site GUSS, il m’a été démontré une technique remarquable : l’utilisation des CTE pour générer une table. Notez l’option MAXRECURSION qui permet de dépasser 100 récursions par défaut. Encore une utilisation magnifique des CTE sur SQL Serveur 2005. A rapprochez de l’article sur GO [count]!

WITH CTETemps AS  
  (  
    SELECT cast('1990-01-01' AS datetime) Date  
    UNION ALL  
    SELECT Date + 1  
    FROM CTETemps  
    WHERE Date + 1 < '2031-01-01'  
  )  
SELECT top 10 * FROM CTETEMPS ORDER BY Date desc OPTION (MAXRECURSION 0);

Dénormaliser une base de données.

Pour optimiser une requete, la premiere des choses à faire, si la ou les tables comptent plusieurs miliers d’enregistrement avec des valeurs trés différentes, est de placer des index, de faire tourner et de supprimer les index non utilisés. Si vous avez exploré toute les possibilités des index, et que votre requete est toujours trop lente, la solution est la denormalisation. La dénormalisation doit être utilisée sans complexe dans les bases en lecture seule, sans mise à jour. Dans les bases transactionnelles, il est nécessaire de mettre en place des triggers pour assurer la cohérence de la base.

Imaginez deux tables en 3 eme forme normale.
element(idelement,nomelement)
structure(id, nom, idelement )
la dénormalisation consiste à garder element à l’identique et modifier structure de la façon suivante (2 eme forme normale):
structure(id,nom,idelement,nomelement)
ainsi la requete associant element et structure est instantannée…
SELECT id,nom,nomelement from structure.

bon developpement

pour aller plus loin, un debat : http://www.developpez.net/forums/showthread.php?t=6231

Certification de DBA avec BrainBench.

Si vous souhaitez certifier vos connaissances en matière de bases de données à destination des entreprises, il existe une alternative à la certification editeur qui demande du temps, de l’argent et une motivation importante.
BrainBench propose sur internet des certifications sur les principales bases de données du marchés.
Un test d’entrainement coute 25 dollars, une certification coute 45 dollars et ils proposent un certains nombre de test gratuitement. C’est 2 fois moins cher qu’une certification microsoft. l’intérêt principal de Brainbech, c’est la possibilité de passer le test en ligne ce qui évite d’aller dans un centre prometric ou vue, de devoir prendre rendez vous dans une grande ville.
Evidemment cela n’a pas la renommée d’une certification MCTS SQL Serveur 2005 mais on peut fournir à l’employeur la preuve que l’on a des compétences sur SQL serveur 7,2000 ou 2005 ou en SQL ANSI.
Je vous recommande d’aller faire un tour sur le site : http://www.brainbench.com/

FILL_FACTOR : Définir le remplissage de l’index.

« Le remplissage de l’index par defaut determine la quantité d’espace que SQL Serveur doit réserver lorsqu’il crée un nouvel index avec les données existantes. La définitition du facteur de remplissage suppose un compromis ; si vous définissez un facteur trop élevé, SQL Serveur ralentit lorsque vous ajoutez des données à une table. Toutefois, un facteur de remplissage fixé trop bas risque d’affecter les performances en lecture de façon inversement proportionnelle au facteur de remplissage. Par exemple, un taux de remplissage de 25% peut diviser les performances en lecture par 4, mais il permet d’accomplir plus rapidement des mises à jour importantes qu’à l’origine. »

Par défaut, le remplissage de l’index est établi à 0. Mais la plage admise s’etend de 0 à 100.

Pour définir un facteur de remplissage, une valeur faible laisse plus de place pour les insertions sans necessiter de fractionnements de pages, mais l’index est plus encombrant.
Une valeur forte laisse moins de place aux insertions mais l’index prend moins de place.

exemple: sp_configure « fill factor (%) »,90

cet exemple configure la valeur par defaut du serveur

mise en place d’une automatisation de backup.

Pour automatiser un backup :

declare
@filename varchar(255),
@heure char(2),
@min char(2),
@date char(8)
set @date=convert(char(8),getdate(),112)
set @heure=datepart(hh,getdate())
set @min=datepart(mi,getdate())
if @heure<=9
set @heure=’0’+@heure
if @min<=9
set @min =’0’+@minset @filename=’G:BACKUPmabase_tran_’+@date+’_’+@heure+’h’+@min+’.trn’
backup log mabase to @filename
go