Denali II. – CDB, avagy önjáró adatbázisok

Az egyik nagyon jópofa dolog a Denaliban a CDB, azaz (Self-)Contained Database, vagyis az öntartalmazó adatbázis. Ez a felhő meg igény szerinti dinamikus kapacitás meg egyéb buzzwordök által lesz tagelve, pedig tényleg értelmes dolog. Arról szól, hogy ha migrálni akarod az adatbázist, akkor benne van (majdnem) minden, neked nem kell loginokat, jobokat, mittoménmiket átvinned, hanem detach, attach, engedélyezet az adatbázisloginokat, jobokat az új szerveren, aztán mehet minden.

(az egyik nagyon jópofa dolog bennem meg az, hogy úgy próbáltam meg megírni ezt a postot, hogy a script hozzá a másik vinyómon maradt… :S Elnézést, mostanság kissé minimál életmódot folytatok, hála a kiváló ténynek, hogy a komplett gépparkunkat kell költöztetni, persze távolról, mert az úgy jó, ha valaki 9 órával odébb tudja csak bedugni a kábelt. most azonban rögtönzöm a scripteket a kis SQL Serveremben.)

Szóval kezdjük a loginokkal:

create database CDBTest
-- ettől lesz CDB az adatbázisunk
alter database CDBTEST SET CONTAINMENT = PARTIAL

use CDBTest
-- csinálok egy logint magamnak...
create login erik with password = 'Password1'
-- ... és csinálok egy CDB usert is. Ilyet csak CDB-ben lehet mondani!
create user erik with password = 'Password2'
-- még a szerver szintjén is be kell állítani, hogy megengedje az azonosítást CDB-ből
exec sp_configure 'contained database authentication', '1'
reconfigure
-- és most lehet tesztelni a logint


Ezen a ponton van egy erik nevű szerver szintű login és egy erik nevű user a CDB-nkben. Nézzünk egy SQLCMD.exe-t!

C:\Local\tmp>sqlcmd -U erik -P Password2 -S .\denali
Msg 18456, Level 14, State 1, Server SW-HUBU-1517\DENALI, Line 1
Login failed for user 'erik'.

C:\Local\tmp>sqlcmd -U erik -P Password2 -S .\denali -d CDBtest
1> exit

C:\Local\tmp>

Láthatóan az első login elbukott – de miért? Mivel nem határoztunk meg kezdeti adatbázist, az SQL Server mindenképpen a masterben akart kezdeni, mint mindig, ahol ez az erik user nem létezik, csak a másik. Mihelyt megadtam az adatbázist a -d kapcsolóval, rögtön bejutottam.

A másik nagyon kedves dolog a collation kezelése. Mint közismert, a collation határozza meg a stringek tárolását és rendezését/összehasonlítását. Apró gond ezzel, hogy a temptáblák mindig a szerver collaitonjével jönnek létre alapból, és ha mozgatjuk az adatbázist, akkor nagy eséllyel szívni fogunk. De a CDB ezt is tudja: kiválóan a temptáblákat az adatbázis collationjével hozza létre. Ez így annak, aki még nem szívott, nem nagy szám. Annak, aki igen, viszont hatalmas. Szemléltető script:

-- eloszor nezzuk a rossz/jelenlegi helyzetet
create database noCDB
-- a szerverem collationje Latin1, elallitom a DB-t masra
ALTER DATABASE noCDB COLLATE Hungarian_CS_AS
use noCDB

-- csinalok egy tablat, az a oszlop collationje Hungarian lesz
create table colltest (a varchar(30))

insert into colltest values('aAbc'),('Ddef'),('Gghi')
-- csinalok egy temptablat, ez Latin1 lesz...
create table #tmptable (a varchar(30))

insert into #tmptable 
select * from colltest 

-- itt jon a hiba...
select * from colltest c
join #tmptable t
on c.a = t.a

drop table #tmptable

A script azt fogja üzenni nekünk (meg mindenkinek, aki szereti), hogy

Msg 468, Level 16, State 9, Line 3
Cannot resolve the collation conflict between “SQL_Latin1_General_CP1_CI_AS” and “Hungarian_CS_AS” in the equal to operation.

Vagyis ledobta a szíjat a szerver: most akkor melyik collation szerint kellene összehasonlítani a stringeket?

Ezzel szemben a CDB-s biznisz kiválóan lefut:

ALTER DATABASE CDBtest COLLATE Hungarian_CS_AS
-- csinalok egy tablat, az a oszlop collationje Hungarian lesz
create table colltest (a varchar(30))

insert into colltest values('abc'),('def'),('ghi')
-- csinalok egy temptablat, es ez is Hungarian lesz!
create table #tmptable (a varchar(30))

insert into #tmptable 
select * from colltest 

select * from colltest c
join #tmptable t
on c.a = t.a
-- no hiba
drop table #tmptable

És íme a nagyszerű. Még egy apró megjegyzés az egyéb dolgok mellett: mint az elején észrevettétek, a SET CONTAINMENT = PARTIAL utasítást használtam. Ez implikálja, hogy van más, teljes, vagyis FULL containment is. Ez igaz, de nem most. Egyelőre csak ez van.

Leave a comment