FILESTREAM - SQLClub

На http://sqlclub. ru/forum/ у мене свого часу була аналогічна тема. Однак sqlclub.ru в даний час недоступний через непорядність людини на ім'я Сергій Заворуєв, який, мабуть, вирішив тишком-нишком присвоїти контент. Доведеться повторити цю тему тут, бо незабаром вона нам знадобиться.

Для підтримки типу FileStream потрібно на рівні бази завести відповідну файл-групу. Як flename для цієї групи виступає локальна папка у файловій системі. Ми не можемо взяти файл по довільному шляху, підсунути його SQL Server і сказати: дивися, це буде твоїм полем файл стрім в такому записі. Як ми побачимо далі, ми можемо лише скопіювати вміст цього файлу в полі, а зберігатиметься він у тому файлі, який відведе йому SQL Server і назве відповідно до своїх правил.

if exists( select 1 from sys . databases where name = 'TestFS' ) begin

alter database TestFS set single_user with rollback immediate

drop database TestFS

create database TestFS on

primary ( name = TestFS_data , filename = 'c:\Temp\TestFS_data.mdf' ),

filegroup FG1 contains filestream

( name = TestFS_media , filename = 'c:\Temp\TestFS_media' )

log on (name = TestFS_log, filename = 'c:\Temp\TestFS_log.ldf')

Ось що з'явилося після створення бази в директорії c:\Temp:

Temp

Прописаний у filestreamівській групі filename являє собою фолдер на локальному диску. Якщо запропонувати файлову кулю, обматерить:

create database TestFS1 on

primary (name = TestFS_data, filename = 'c:\Temp\TestFS_data.mdf'),

filegroup FG1 contains filestream

(name = TestFS_media, filename = '\192.168.0.1\c$\Temp\TestFS_media')

logon (name = TestFS_log, filename = 'c:\Temp\TestFS_log.ldf')

Msg 5135, Level 16, State 2, Line 1

The path '\192.168.0.1\c$\Temp\TestFS_media' може бути використаний для FILESTREAM files. Для отримання інформації про supported paths, pozri SQL Server Books Online.

Msg 1802, Level 16, State 2, Line 1

CREATE DATABASE failed. Кілька файлів наклейок не можна створювати. Check related errors.

Зазначений шлях має існувати аж до n -1-го рівня, у разі - c:\Temp. Фолдер TestFS_media існувати не повинен.

Можна створювати кілька файл-груп типу файл стрім:

create database TestFS1 on

primary ( name = TestFS_data , filename = 'c:\Temp\TestFS_data1.mdf' ),

filegroup FG1 contains filestream

( name = TestFS_media1 , filename = 'c:\Temp\TestFS_media1' ),

filegroup FG2 contains filestream

( name = TestFS_media2 , filename = 'c:\Temp\TestFS_media2' )

log on (name = TestFS_log, filename = 'c:\Temp\TestFS_log1.ldf')

однак у файл стримівській файл групі може бути прописаний лише один фолдер. Так робити не можна:

filegroup FG 1 contains filestream

(name = TestFS_media, filename = 'c:\Temp\TestFS_media'),

(name = aaa, filename = 'c:\aaa')

Тобто. автоматично розганяти файл стримівські файли по різних папках не вийде.

Після створення бази з файл стримівської файл-групою можна створювати таблиці з файл стримівськими полями. В операторі CREATE TABLE поле типу filestream – це звичайний блоб (varbinary (max)) з атрибутом filestream.

create table Media (

>int identity primary key ,

[gu >uniqueidentifier default newid() unique rowguidcol not null,

[fileName] nvarchar ( 256 ),

contentTypenvarchar ( 256 ),

blob nvarchar (max),

stream varbinary ( max ) filestream

За наявності у таблиці поля filestream обов'язковим також є наявність поля unique lang=RU> Хоча unique > на те й unique lang=RU>, щоб бути unique , ця умова потрібна, щоб, наприклад, новий запис не потрапило значення з попередньої. Крім того, оптимізатор набагато радісніше почувається, коли бачить явний unique. Атрибут rowguidcol дозволяє звертатися до поля не на ім'я, а як $ rowgu lang=RU>: напр., select $rowguid from Media. Зрозуміло, що таке поле має бути одне на таблицю. Яку важливість привносить цей атрибут, я, чесно кажучи, сказати не беруся. Просто бувають ситуації, які його вимагають, і тому. Раніше до них належала merge-реплікація, зараз ось додався файл стрім.

Наявність primary key є обов'язковим. В даному випадку ми могли б обійтись без поля > простіше, ніж запам'ятовувати гуїд.

Апостеріори дізнатися, чи має поле атрибут filestream, можна так:

select * from sys. columns where object_id = object_id ( 'Media' , 'table' ) and system_type_ >= type_id ( 'varbinary' ) and max_length = - 1 and is_filestream = 1

Після створення таблиці в C:\Temp\TestFS_media (параметр filename групи filestream при створенні бази) з'явилася директорія на ім'я деякого гуїда, що відповідає таблиці, в ній - ще одна теж з ім'ям якогось гуїда, що відповідає полю filestream у цій таблиці (їх може бути кілька за кількістю таких полів).

Temp

Temp

Temp

Давайте тепер додавати до неї записи:

insert Media ( stream ) values ​​( cast ( N'aaa' asvarbinary (max)))

insert Media ( stream ) values ​​( cast ( N'bbb' as varbinary ( max )))

insert Media ( stream ) values ​​( cast ( N'ccc' as varbinary ( max )))

Після вставки в листовій директорії з'явилося три файли з іменами гуїдів, що відповідають трьом вставленим записам. Під NULLове значення файл не заводиться, у блобі має бути щось непусте. Порожній рядок – це вже не порожнеча.

Temp

Ось ми його підредагували:

зберегли та подивилися, що вийшло:

select *, cast (stream as nvarchar (max)) from Media

sqlclub

Як приклад того, як це все перебуває під контролем SQL Server, подивимося, як файл стрим бекапаться разом з базою. Робимо

backup database TestFS на диск = 'c:\Temp\Test_FS.bak' with init

Потім драпаємо базу, при цьому фолдер TestFS_media зникає з c: \ Temp разом з усіма своїми файлами, в яких зберігалося вміст поле файл стрім від різних записів таблиці Media. Ресторим базу:

restore database TestFS від диску = 'c:\Temp\Test_FS.bak' with move 'TestFS_media' до 'c:\aaa'

TestFS_media

Тут W I TH MOVE – стандартна опція, в якій при відновленні вказується, що логічні імена файлів тепер відповідатимуть іншим фізичним шляхам. Ми говоримо, що c:\Temp\TestFS_media переїжджає у з:\aaa. При цьому на диску з автоматично створюється фолдер aaa, куди розгорнулася файл стримівська файл група. Так само, як і під час створення бази, весь зазначений шлях має існувати від кореня диска рівня n-1, тобто. якби ми сказали with move 'TestFS_media' to 'c:\aaa\bbb', не прокотило б.

Як і HierarchyID, про який я неабияк розмовляв у попередніх постах, і геопросторові типи, розмови на тему яких щепопереду, тип filestream підтримується в безкоштовному SQL Server, який SQL Express. Більш того, обмеження на розмір бази для SQL Express не поширюються на дані, що лежать у файл стримівських блобах.