Почему BLOB-поле - недополе, и как его сделать полем

Сегодня всё больше и больше встречается мультимедийных данных - картинок, мелодий, песен, фильмов. Современная тенденция - хранить их в базе данных, а не в файловой системе. Научные графические данные попросту неудобно хранить вне базы данных, т.к. они сопровождаются большим количеством дополнительных цифровых данных. Две наиболее типичные операции с BLOB'ами - это:

  1. скачивание (с сервера, в т.ч. с СУБД);
  2. получение (от клиента, который отправляет его по собственной инициативе).

Перечислим, какие задачи они порождают, и предложим, как их решить.


Скачивание

Соединения иногда разрываются. Кроме того, может понадобится перезагрузить компьютер-получатель или выключить ноутбук-получатель. Таким образом, в поле нужно хранить:

 
  • внешний адрес 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


Автор заинтересован во мнениях, комментариях и возможной реализации этих предложений. Все предложения являются общественным достоянием.

Дмитрий ТЮРИН,
главный специалист департамента ЦАБС "АСБ Беларусбанк"

  1. Предполагаем, что имя схемы объединено вместе с именем таблицы в один токин
  2. Было бы очень глупо, если бы программист должен был создавать последовательность для BLOB'ов и по триггеру для каждого BLOB-поля в базе данных
  3. Хорошо, если бы СУБД понимала большое количество форматов и исправляла бы тип файла в BLOB-поле на значение из содержимого файла
  4. Вида "site.com/~dbowner/dbname/identifier" или "111.222.333.444/~dbowner/dbname /identifier"
  5. Знать тип 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 атрибуты.
Версия для печатиВерсия для печати

Номер: 

07 за 2009 год

Рубрика: 

Software
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!
 

Комментарии

Страницы

Аватар пользователя mike
Нда. 5 раз перечитать -- круто!
Аватар пользователя Колесников А.
...искренне силился проникнуться проблемой:)... и название понравилось :)))) поле, полуполе, недополе ...
Аватар пользователя Fedor78
>Дмитрий ТЮРИН,

главный специалист департамента ЦАБС "АСБ Беларусбанк"

Уважаемый специалист :)

Прежде чем что-то писать поинтересовались бы вы как используются эти поля. А то получается что в ваших Blob-полях вы храните картинки, я то храню иногда другие данные. При выдачи ссылок, то у вас будут проблемы. Обучать вас этому не буду, т.к. это стоит денег.

Я понимаю что предметы ТОХОД, БД или ТБДЗ прошли мимо.

Аватар пользователя mike
Также понятно, что предмет "русяз" для уважаемого Фёдора тоже прошёл мимо.
Аватар пользователя Фидошник
Да, майк, согласен. К сожалению, не только у него.
Аватар пользователя Fedor78
>mike (old student)

>Также понятно, что предмет "русяз" для уважаемого Фёдора тоже прошёл мимо.

У меня такого предмета не было. У меня был Русский язык :)

Аватар пользователя mike
>У меня был Русский язык :)

И куда пропал?

Аватар пользователя Андрей Ходотов
Мдя. Купился на другую статью того же автора - "Полный контроль доступа в базе данных" (http://kv.by/index2009051107.htm). Начал искать - что ж это за СУБД такая интересная описана? (С забавными ключевыми словами BESTOW/VANISH вместо привычных GRANT/REVOKE). Нашёл:

http://sql50.narod.ru/

Уважаемая редакция, отсеивайте, пожалуйста, графоманов!

Страницы