Сегодня всё больше и больше встречается мультимедийных данных - картинок, мелодий, песен, фильмов. Современная тенденция - хранить их в базе данных, а не в файловой системе. Научные графические данные попросту неудобно хранить вне базы данных, т.к. они сопровождаются большим количеством дополнительных цифровых данных. Две наиболее типичные операции с BLOB'ами - это:
- скачивание (с сервера, в т.ч. с СУБД);
- получение (от клиента, который отправляет его по собственной инициативе).
Перечислим, какие задачи они порождают, и предложим, как их решить.
Скачивание
Соединения иногда разрываются. Кроме того, может понадобится перезагрузить компьютер-получатель или выключить ноутбук-получатель. Таким образом, в поле нужно хранить:
- внешний адрес BLOB'а для продолжения скачивания;
- уже скачанную часть BLOB - и даже части, если СУБД может разделять удалённый BLOB на несколько частей (подобно обычным программам для скачивания, например "ReGet") и скачивать каждую часть через отдельное TCP-соединение;
- смещения начала и конца каждой части для продолжения скачивания и сборки в единый BLOB.
И нам нужны операторы:
- возвращающий BLOB;
- возвращающий процент завершённости скачивания;
- возвращающий адрес BLOB'а на удалённом сервере (вместо NULL'а, чтобы уведомить запрашивающего BLOB, что скачивание ещё не закончено, и уведомить, где можно получить BLOB до завершения скачивания или в случае, если СУБД будет разрушена);
- запускающий скачивание в фоновом режиме (т.е. разрешающий выполнение следующих SQL-операторов в процессе скачивания) и сообщающий, запущено скачивание или нет
Получение
Мы не можем продолжить получение после разрыва TCP-соединения, после перезагрузки или выключения питания - мы можем только надеяться, что соединение не будет разорвано, компьютер не повиснет и что источник бесперебойного питания дотянет до конца передачи. Но если кто-нибудь попросит СУБД выдать этот BLOB в процессе получения, что СУБД должна ответить ему ? Отвечая NULL, она сообщит, что ничего не знает о BLOB'е, что является ложью, т.к. получение BLOB'а - это только вопрос времени.
Таким образом, мы видим, что поле должно хранить:
- уже полученную часть BLOB;
- значение "ACCEPTING", подобное NULL, но не равное ему.
Пусть третья база данных копирует BLOB-поле в себя в тот момент, когда наша база данных его ещё получает. Может ли третья база данных содержать значение "ACCEPTING"? Очевидно нет, т.к. это выглядело бы так, будто третья база данных сама получает BLOB. Таким образом, третья база данных дезинформировала бы своих пользователей и внушила бы им ложные надежды. Итак, нам нужно ещё одно значение, подобное NULL, например:
- значение "NOTGOT"
в которое превращается "ACCEPTING". NOTGOT превращается в NOTGOT при копировании.
Оба случая
Следует заметить, что BLOB - это часто картинка, которая должна быть продемонстрирована в клиенте (например, в браузере). И было бы очень неудобно, если бы адрес содержал имя BLOB-поля (чтобы отличить его от других BLOB-полей), имя поля первичного ключа (чтобы указать запись) и имя таблицы1. И как записать такой адрес? Это будет совершенно не похоже на URL, кроме того, клиент совершенно не обязан знать SQL. Таким образом, мы видим, что:
- идентификатор, уникальный во всей базе данных
должен быть помещён в BLOB-поле сразу, как только BLOB будет скачан или получен полностью. Помещение должно выполняться СУБД автоматически, без участия программиста2;
Вообще же BLOB - это файл, и как всякий файл, он имеет тип - jpg, mpg, и т.д. Файлы одних форматов содержат указание типа в самом начале файла, файлы других форматов - не содержат, и в этом случае тип должен храниться в BLOB-поле и копироваться из поля в поле при копировании BLOB'а3.
- тип файла.
Резюме
Давайте подытожим: BLOB-поле должно быть способно содержать один из следующих наборов значений:
- значение NULL
или
- значение ACCEPTING
- тип файла
- одну часть (начало) BLOB'а
или
- значение NOTGOT
или
- идентификатор, уникальный во всей базе данных
- тип файла
- целый BLOB
или
- URL4
- тип файла
- несколько частей BLOB'а
- смещения начала и конца каждой части BLOB'а.
Операторы, упомянутые выше, будут выглядеть так:
- "SELECT fieldname ..." - для извлечения BLOB'а
- "SELECT ID(fieldname) ..." - для извлечения идентификатора BLOB
- "... WHERE fieldname=542" - для указания записи по идентификатору BLOB, равному 542
- "SELECT PERCENT(fieldname) ..." - для извлечения процента завершённости скачивания
- "SELECT TYPE(fieldname) ..." - для типа BLOB'а5
- "SELECT DOWNLOAD(fieldname) ..." - для запуска скачивания в фоновом режиме и для информирования, запущено скачивание или нет (т.е. возвращает Y/N)
- "SELECT STOP(fieldname) FROM * WHERE fieldname=542" - для остановки скачивания BLOB'а с идентификатором, равным 542
Автор заинтересован во мнениях,
комментариях и возможной
реализации этих предложений. Все
предложения являются общественным
достоянием.
Дмитрий ТЮРИН,
главный специалист департамента
ЦАБС "АСБ Беларусбанк"
- Предполагаем, что имя схемы объединено вместе с именем таблицы в один токин
- Было бы очень глупо, если бы программист должен был создавать последовательность для BLOB'ов и по триггеру для каждого BLOB-поля в базе данных
- Хорошо, если бы СУБД понимала большое количество форматов и исправляла бы тип файла в BLOB-поле на значение из содержимого файла
- Вида "site.com/~dbowner/dbname/identifier" или "111.222.333.444/~dbowner/dbname /identifier"
- Знать тип BLOB'а нужно,
только чтобы отобрать BLOB'ы для
конвертирования из одного
формата в другой. При пересылке
BLOB'а его тип отдельно
запрашивать не надо, т.к. он
обязан автоматически
извлекаться вместе с BLOB'ом,
например (проприетарный формат
передачи данных конкретной
СУБД для удобства его
визуализации записан в XML-виде,
подробности этой записи и
вариант её возможного
транспортного использования
представлены на слайдах #141-143
презентации sql50.euro.ru/sql5.17.0.pdf)
<tablename fieldname1= fieldname="3652435"/>
<?file value="3652435" type="mpg" size="3">Y29</?file>
BLOB'ы передаются не в xml-атрибуте, а после всех xml-элементов. Иначе бы они блокировали реакцию получателя на быстро передаваемые неBLOB атрибуты.
Комментарии
Страницы
Автор заинтересован во мнениях, комментариях и возможной реализации этих предложений. Все предложения являются общественным достоянием
<<<<<
я думаю надо помочь крупнейшему банку страны в понимании вопроса.
я открыт для обсуждения - учитывая статью оно просто необходимо.
PS. Интересно, а беларусбанке есть вменяемые специалисты в написании ПО или это эффект главного специалиста ?
Cтатья, знаете, как-то уж очень пугает. Скажите, Беларусбанк вообще собирается переходить на открытый стандард Unix (FreeBSD, Linux) ? Что у вас там вообще творится ? Мы сейчас ведёмся на пиар технологий, чтоб в конечном итоге превратиться в дойную корову Билла Гейтса? Или всё же ищем менее распиаренные, но зато наиболее эффективные и к тому же ещё бесплатные и открытые решения?
В общем, можете для начала установить lighttpd - сверхбыстрый сервер, производительность отдачи статики значительно выше чем Apache. Кстати, на нём работает Youtube.
Советую писать на С++ с помощью wxWidgets, Qt (эти мощные кроссплатформенные библиотеки абсолютно бесплатны для разработчиков закрытого коммерческого ПО, и там есть уже готовые database layers). Вместо PHP можно ещё пробовать использовать FastCGI - не пугайтесь, там всё просто, учится это дело вообще за 2 дня, только предупреждаю, такие системы мало кто пиарит, это не выгодно ни монстрам типа Microsoft, ни 1С, ни Sun, и ни тем кто кормится за счёт этих монстров.
Страницы