Реляционная файловая система от Microsoft
Автор статьи — Самородов Федор Анатольевич,
преподаватель-эксперт Центра «Специалист»
На самом деле речь, конечно, пойдёт не о какой-то принципиально новой файловой системе, а об одном очень интересном нововведении в SQL Server 2012. В современных СУБД сложно придумать что-то принципиально новое. Но, с другой стороны, современные СУБД стали настолько функциональны, что посмотрев на них под нетрадиционным углом, можно обнаружить неожиданные варианты применения их возможностей.
О механизмах хранения
Какую бы файловую систему вы ни использовали, её главная функция – преобразование логических ссылок на данные в физические. Логическая единица, с которой удобно работать пользователю – файл. Мы создаём, редактируем и удаляем файлы, не задумываясь о том, как именно они хранятся. Вопросы хранения – это задача файловой системы, именно она отслеживает соответствие между логическими единицами хранения (файлами) и физическими – секторами или кластерами.
Например, файловые системы типа FAT и NTFS преобразуют имена файлов в цепочки кластеров. Пользователь работает с файлом ReadMe.txt, а файловая система помнит, что этот файл начинается на кластере №15, продолжается на секторе №132 и заканчивается на кластере №4. Если бы не было такого механизма абстрагирования от физической адресации, пользователю пришлось бы оперировать неудобными номерами секторов вместо удобных имён файлов.
Ещё пример. Работая с базой данных, пользователь использует имена таблиц. А механизм хранения, встроенный в СУБД, преобразует обращение к таблицам в работу с дисковыми страницами. В СУБД SQL Server для этого используется механизм кучи (heap) или кластеризованный индекс, которые решают ту же задачу, что и файловая система. СУБД знает, что таблица Customers (логическая единица хранения) лежит в таком-то файле и начинается на странице с номером…
Таким образом, файловые системы (и в целом механизмы хранения) с одной стороны общаются с пользователем на удобном для него языке и предоставляют ему возможность работать с логическими единицами хранения, а с другой стороны – с системой хранения, общаясь с ней, используя физические термины.
FileStream и FileTables
В предыдущей версии SQL Server появилась интересная возможность хранить строки таблиц напрямую в файлах – механизм хранения FileStream. То есть, с одной стороны вы работаете с данными, как со строками таблиц, через СУБД, используя язык SQL со всеми его преимуществами (например, получая транзакционную целостность). А с другой – можете работать с этими же данными, как с файлами на диске, опять же получая преимущества такого доступа (в том числе, низкую стоимость хранения).
Однако механизм FileStream в 2008-й версии нельзя назвать файловой системой, потому что при его использовании не решается задача простого и прозрачного преобразования одной системы адресации в другую. С одной стороны у вас есть строка в таблице, содержащая какие-то полезные данные. Как узнать имя файла, в котором эта же строка представлена на диске? Да, для приложения есть способ это сделать, но его нельзя назвать простым и прозрачным для пользователя.
В 2012-й версии SQL Server этот недостаток устранён. Над механизмом FileStream появилась интересная надстройка – файловые таблицы (FileTables). Эти таблицы, как и механизм FileStream, используют для хранения строк файлы, но при этом позволяют вам не только легко видеть имена этих файлов, но и полноценно ими управлять. Вы можете задавать произвольные имена файлов, каталогов, расширения, а также всевозможные файловые атрибуты.
Как это выглядит
Файловые таблицы имеют заранее определённую структуру и обвязку (индексы, ограничители).
Каждая строка связана со своим файлом. Точнее говоря, она этим файлом и является. Нетипизированный столбец file_stream – это содержимое файла в чистом виде. Поскольку это бинарный объект, хранить в нём можно что угодно и любого размера (лишь бы места на диске хватило). Столбец name и вычисляемый от него file_type – это имя файла (вместе с расширением) и расширение файла.
Обратите внимание на первичный и внешний ключи. Это пара столбцов иерархического типа. Дело в том, что помимо файлов, строки этой таблицы могут представлять собой каталоги (флаг is_directory). Как видите, структура таблицы специально спроектирована для того, чтобы точно отражать содержимое файлового каталога вместе со всеми вложенными файлами. Также имеются столбцы, соответствующие файловым атрибутам (флаги, дата и время модификации/доступа).
Самое интересное заключается в том, что вы можете работать с содержимым этой таблицы как средствами SQL, так и при помощи файловых инструментов.
Например, можно просто добавить в таблицу строки таким образом:
INSERT
INTO MyDocs (name, file_stream)
VALUES ('Read me.txt', CAST ('My text' AS varbinary (MAX))),
('Default.html', CAST ('
My header
' AS varbinary (MAX)))
После чего сразу эти файлы сразу видны в папке, заданной при настройке базы данных.
А можно, наоборот, изменить или создать файлы в проводнике и тут же увидеть результат изменения в таблице.
В предыдущей версии SQL Server можно было использовать сам принцип файлового хранения, но у пользователя не было такого прозрачного способа сопоставить строку с файлом. Разработчику приходилось писать приложение таким образом, чтобы оно сначала обращалось к базе данных и только после этого могло открыть файл. Кроме того, удаление файла с диска не вызывало автоматического удаления записи в таблице. Теперь у нас есть настоящая реляционная файловая система. Соответствие между реляционными и файловыми единицами хранения поддерживается автоматически.
Как настроить файловый механизм хранения
Для того, чтобы можно было использовать файловые таблицы, базу данных и сервер необходимо подготовить.
Во-первых, поскольку эффект от использования файловых таблиц заметен снаружи SQL Server, администратор Windows должен разрешить использование файлового механизма хранения на уровне всего экземпляра. Это делается в диспетчере конфигурации в настройке службы SQL Server.
Как минимум, необходимо разрешить FileStream при доступе через Transact-SQL. Также, очевидно, следует включить возможность файлового доступа, иначе вся затея будет лишена практического смысла. А последняя галочка позволит работать с файлами через общую папку с удалённой машины.
Во-вторых, администратор SQL Server выдаёт разрешение на использование FileStream на уровне всего экземпляра. Это можно сделать в интерфейсе SSMS в свойствах сервера, либо при помощи Transact-SQL (в любом случае службу необходимо перезапустить):
EXECUTE sp_Configure filestream_access_level, 2
RECONFIGURE
В третьих, настройки на уровне базы данных. Необходимо указать каталог на диске, в котором будут физически храниться строки файловых таблиц. Для этого нужно создать хотя бы одну файловую группу типа FileStream и хотя бы один файл в ней. На самом деле это будет даже не файл, а ссылка на папку (вместо физического имени файла указывается каталог). Теперь можно создавать таблицы с механизмом хранения FileStream в стиле SQL Server 2008, но для создания более удобных файловых таблиц необходимо задать ещё имя каталога и разрешить доступ к данным со стороны файловой системы. Это похоже на те настройки, которые мы видели в диспетчере конфигурации, но они применяются не ко всему серверу, а к каждой базе данных индивидуально. Установить имя каталога можно в окне свойств базы данных в SSMS или через Transact-SQL:
ALTER DATABASE MyDatabase
SET FILESTREAM (
NON_TRANSACTED_ACCESS = FULL,
DIRECTORY_NAME = N'ИмяКаталогаБазы'
)
Теперь можно создавать файловые таблицы. Поскольку их структура уже заранее определена, написать команду Transact-SQL будет проще:
CREATE TABLE MyTable
AS FILETABLE
WITH (
FILETABLE_DIRECTORY = 'ИмяКаталогаТаблицы'
)
Всё, можно работать. Теперь строки этой таблицы будут полноценно доступны по такому адресу:
\\ИмяСервера\ИмяОбщейПапки\ИмяКаталогаБазы\ИмяКаталогаТаблицы
Одно замечание. При планировании файловых таблиц примите во внимание чисто техническое ограничение на работу с этими файлами – не работает отображение в память. То есть, открыть локально эти файлы, к примеру, блокнотом не получится. Это ограничение касается только нового механизма – FileTable. Работать с FileStream-данными (в стиле SQL Server 2008) в режиме memory-mapped разрешено.
Для чего использовать файловые таблицы на практике
Разработчики современных приложений часто оказываются в ситуации, когда в базе данных приходится хранить документы довольно большого объёма, но внутри самой базы эти документы никак не обрабатываются. Они лишь сохраняются в базе и затем извлекаются из неё для последующей обработки в приложении. Что делать, к примеру, с аудио- и видеоданными, с изображениями?
Можно хранить их, как и все остальные данные, в таблицах. Это удобно, так как мы получаем транзакционную целостность и другие преимущества, предоставляемые СУБД. Но стоимость хранения данных в таблицах заметно больше, чем расходы на хранение тех же данных в виде обычных файлов.
Или хранить такого рода данные в виде файлов на диске, а в базе хранить лишь ссылки на них (имена и пути). Всё равно ведь мы не собирались обрабатывать эти данные внутри базы. Этот подход дешевле, но теряется автоматическая поддержка целостности. Например, администратору для выполнения резервного копирования теперь необходимо сохранить резервную копию не только базы данных, но и папок на диске.
Хорошим компромиссом будет использование файловых таблиц. Низкие накладные расходы при одновременной возможности использования SQL-транзакций. Кстати, хранение данных в режиме FileStream позволяет обойти встроенное ограничение SQL Server на размер данных в ячейке таблицы. Для обычных ячеек данных (image, text, varbinary) лимит хранения – 2 гигабайта. Если же вы используете файловое хранение, то размер данных в ячейке (он же размер файла) ограничен лишь размером тома.
Современные объёмы хранимых данных требуют новых подходов. Используйте вашу СУБД на полную мощность!
Статья опубликована в журнале «Системный администратор» (№4, 2012):