Страницы

Поиск по вопросам

пятница, 1 февраля 2019 г.

Хранение файлов в базе vs хранение в файловой системе

Хотелось бы увидеть + и - различных видов хранения, и когда какой лучше использовать.
С файловыми таблицами, я не работал, но я предполагаю, что там меньше головной боли с файловыми операциями, например файл не может быть блокироваться процессом, наверное есть транзакции(Т.е нельзя убить файл, если вдруг при добавлении его в таблицу, клиент отвалится). Поправьте если я не прав.
UPD: Enttity Framework дружит с файловыми таблицами?


Ответ

В SqlServer вы можете использовать следующие варианты (некоторые из них применимы и к другим СУБД).
Вариант 1
В БД хранится "заголовок" файла (например, путь к файлу плюс, возможно, какой-то набор атрибутов):
create table [TableName] ( ... FilePath nvarchar(4000) not NULL, ... )
а данные хранятся отдельно в файловой системе. Размер БД меньше, чем если хранить в БД также и данные. Но нужно следить за ситуациями "файл есть, заголовка нет" или "заголовок есть, файла нет". На мой взгляд, если файлы являются логически важной частью данных БД (не кэш, не какие-то временные данные), то лучше посмотреть на другие варианты.
Вариант 2
В БД хранится также и содержимое файла (в столбце типа varbinary(max)).
create table [TableName] ( ... FileData varbinary(max) FILESTREAM not NULL, --либо --FileData varbinary(max) not NULL, ... )
Здесь две опции - с FILESTREAM и без.
Без FILESTREAM
данные хранятся в БД (в т.н. LOB pages) размер данных одного элемента ограничен 2Gb
С FILESTREAM
данные хранятся в файловой системе (именно как файлы) нет ограничения в 2Gb на элемент данные FILESTREAM не участвуют при подсчёте лимита на макс. размер БД (к чему чувствительны Express Edition) к данным можно получить доступ через соотв. API со стороны файловой системы (SqlServer 2014 и далее) запрашиваемые данные не отъедают из buffer pool, оставляя больше памяти для обработки запросов
И с FILESTREAM и без поддерживаются транзакции. С FILESTREAM при доступе через Transact-SQL поддержка полная, при доступе через файловую систему есть ограничения (смотреть здесь).
Вариант 3
Использование таблиц специального типа FileTable
create table [FileTableName] as filetable
Их функционал основан на использовании FILESTREAM. Таблица представляет иерархию хранящихся файлов/директорий, их данные и атрибуты. В варианте 2, чтобы создать/удалить файл, нужно создать/удалить соотв. запись в таблице. В данном варианте это можно делать напрямую через файловую систему. Например зайти в соответствующую директорию (SqlServer создаёт для этого соответствующую UNC share), создать какой-то файл/директорию, удалить/изменить, потом сделать запрос select * from FileTableName и увидеть соответствующие изменения. И наоборот - при вставке записи в таблицу через SQL в директории появится соответствующий файл или директория.
Какой вариант когда лучше использовать - думаю, зависит от конкретной задачи. В документации более детальное описание и сравнение вариантов 2 и 3.

Комментариев нет:

Отправить комментарий