Se afișează postările cu eticheta SQL Server. Afișați toate postările
Se afișează postările cu eticheta SQL Server. Afișați toate postările

miercuri, 20 februarie 2008

SQL Server 2008 February CTP

Mai e o saptamana pana la lansarea oficiala a Visual Studio 2008 si Windows Server 2008... si dupa cum deja se stie, SQL Server 2008 a fost amanat cateva luni.

A aparut insa un February CTP de SQL Server 2008 pe care il puteti downloada si testa: http://www.microsoft.com/downloads/details.aspx?FamilyId=749BD760-F404-4D45-9AC0-D7F1B3ED1053&displaylang=en

Pentru mai multe detalii referitor la ce aduce nou acest CTP fata de cel din noiembrie: https://connect.microsoft.com/SQLServer/content/content.aspx?ContentID=5470

marți, 12 februarie 2008

Tipul de date hierarchyid in SQL Server 2008

SQL Server 2008 introduce un nou tip de date pentru modelarea structurilor ierarhice numit hierarchyid.

In aproape toate proiectele mai mari la care am lucrat pana acum am avut nevoie de o structura ierarhica... ca era vorba de un bill of materials, sau categorii organizate pe mai multe nivele, intotdeauna tabela continea o coloana cu referinta spre o alta coloana din aceeasi tabela.

Cu alte cuvinte pe SQL 2000 si 2005 o astfel de tabela arata astfel:
CREATE TABLE Hierarchy (
Id int PRIMARY KEY IDENTITY(1, 1),
ParentId int
.....

)

De cele mai multe ori, pentru a evita aparitia nodurilor orfane, se adauga si o constrangere de tip foreign key pe coloana ParentId (solutie care functioneaza doar daca se adauga in mod deliberat un nod de root cu ParentId = NULL si care nu va fi niciodata sters).

In SQL Server 2008 s-a introdus un nou tip de date hierarchyid care permite modelarea acestor structuri ierarhice intr-un mod mult mai eficient. Deci tabela anterioara o vom putea crea cu structura:
CREATE TABLE Hierarchy2 (
Id hierarchyid,
...
)

Nu am sa intru in prea multe detalii, pentru ca puteti gasi pe MSDN foarte multe informatii despre:

Acestea fiind spuse, sa trecem la treaba... bineinteles ca prima mea intrebare a fost: "ok, la ce bun un nou tip de date, daca o structura ierarhica mi-o puteam defini simplu cu relatii parinte-copil?"

Primul lucru la care m-am gandit a fost sa testez cum se comporta din punct de vedere al performantei... asa ca mi-am creat doua tabele cu urmatoarele structuri:

1. Folosind relatii de tip parinte-copil:
CREATE TABLE Hierarchy (
Id int PRIMARY KEY IDENTITY(1, 1),
ParentId int REFERENCES Hierarchy(Id),
Name nvarchar(50)
)
CREATE INDEX IDX_ParentId ON Hierarchy(ParentId)

2. Folosind noul tip de date hierarchyid
CREATE TABLE Hierarchy2 (
Id hierarchyid,
Level as Id.GetLevel(),
Name nvarchar(50)
)

CREATE CLUSTERED INDEX IDX_Hierarchy2_BF ON Hierarchy2(Level, Id)
CREATE UNIQUE INDEX IDX_Hierarchy2_DF ON Hierarchy2(Id)

Pentru ca diferenta de performanta sa fie vizibila, mi-am generat in ambele tabele cate 406901 inregistrari (25 de copii pentru fiecare nod, iar la al 4-lea nivel m-am oprit... deci 1 (root-ul) + 25 nivel 1 + 25 * 25 nivel 2 + 25 * 25 * 25 nivel 3 + 25 * 25 * 25 * 25 nivel 4).

Pentru structura clasica de tabela, pentru a obtine toti copii descendenti ai unui nod, se face o parcurgere pe latime a arborelui... la fiecare pas se adauga intr-o tabela temporara toti copii directi ai nodurilor de pe ultimul nivel vizitat, apoi se trece la urmatorul nivel.

Cazul cel mai defavorabil este cand nodul de plecare este chiar radacina:

1. Parcurgerea tabelei construita prin relatii parinte-copil:
DECLARE @ParentId int
SET @ParentId = 1
DECLARE @Level int
SET @Level = 1

CREATE TABLE #Hierarchy (Id int, [Level] int, Name nvarchar(50))
INSERT INTO #Hierarchy
SELECT Id, @Level, Name
FROM Hierarchy
WHERE @ParentId = ParentId

WHILE EXISTS (SELECT *
FROM Hierarchy WITH (NOLOCK)
WHERE ParentId IN (SELECT Id
FROM #Hierarchy WITH (NOLOCK)
WHERE [Level] = @Level))
BEGIN
INSERT INTO #Hierarchy (Id, [Level], Name)
SELECT Id, @Level + 1, Name
FROM Hierarchy WITH (NOLOCK)
WHERE ParentId IN (SELECT Id
FROM #Hierarchy WITH (NOLOCK)
WHERE [Level] = @Level)

SET @Level = @Level + 1
END
DROP TABLE #Hierarchy

2. Parcurgerea tabelei construita cu nou tip de date hierarchyid:
CREATE TABLE #Hierarchy2 (Id hierarchyid, [Level] int, Name nvarchar(50))

DECLARE @Level int, @Parent hierarchyid
SET @Level = 1
SELECT @Parent = Id
FROM Hierarchy2
WHERE Id = '/'


WHILE EXISTS (SELECT *
FROM Hierarchy2 (NOLOCK)
WHERE Id.GetAncestor(@Level) = @Parent)
BEGIN
INSERT INTO #Hierarchy2
SELECT Id, Level, Name
FROM Hierarchy2 WITH (NOLOCK)
WHERE Id.GetAncestor(@Level) = @Parent

SET @Level = @Level + 1
END
DROP TABLE #Hierarchy2

Concluzii:

- in primul caz, parcurgerea a durat 3 secunde, iar folosind hierarchyid parcurgerea a fost instanta; deci performantele sunt net superioare folosind noua structura;

- script-ul de parcurgere al tabelei cu hierarchyid este mult mai simplu si usor de modificat.

duminică, 25 noiembrie 2007

Tipuri noi de date pentru date/time in SQL Server 2008

In versiunile 2000/2005 de SQL Server exista doua tipuri de date pentru salvat informatii de tip data/timp:
- datetime: valori permise intre 1/1/1753 - 31/12/2999 cu precizie de 3.33 milisecunde.
- smalldatetime: valori permise intre 1/1/1900 - 6/6/2079 cu precizie de 1 minut.

SQL Server 2008 introduce noi tipuri de date care rezolva partial problemele de precizie si timezone:
1. date: valori intre 1/1/0001 - 31/12/9999 cu precizie de 1 zi.
2. time: valori intre 00:00:00.0000000 - 23:59:99.9999999 cu precizie de 100 nanosecunde.
3. datetime2: reprezinta o combinatie intre tipurile date si time cu valori intre 1/1/0001 00:00:0000000 - 31/12/9999 23:59:99.9999999 cu precizie de 100 nanosecunde.
4. datetimeoffset: cu ajutorul acestui nou tip de date se pot salva datele impreuna cu offset-ul fata de UTC. Tipul nou permite valori intre 1/1/0001 00:00:00 - 31/12/9999 23:59:99.9999999 iar offset-ul intre -14:00 si +14:00.

Marele minus al datetimeoffset-ului e ca nu tine cont de Daylight Saving.