MySQL Binary Storage с использованием файловой системы BLOB VS OS: большие файлы, большие объемы, большие проблемы - PullRequest
20 голосов
/ 11 января 2011

Версии, которые я использую (в основном самое последнее):
PHP: 5.3.1
MySQL: 5.1.41
Апач: 2.2.14
ОС: CentOS (последняя версия)

Вот ситуация.

У меня есть тысячи очень важных документов, от контрактов с клиентами до голосовых подписей (записи авторизации клиентов для контрактов), с типами файлов, включая, но не ограничиваясь, jpg, gif, png, tiff, doc, docx, xls, WAV, MP3, PDF и т. д.

Все эти документы в настоящее время хранятся на нескольких серверах, включая 32-разрядную версию Windows, CentOS и Mac, а также другие. Некоторые файлы также хранятся на настольных компьютерах и ноутбуках сотрудников, а некоторые все еще являются печатными копиями, хранящимися в сотнях коробок и картотек.

Теперь, поскольку клиенты или юристы могут требовать подтверждения контрактов в любое время, моя компания должна иметь возможность эффективно искать и находить нужные документы, по этой причине ВСЕ эти файлы должны быть оцифрованы (если это еще не сделано). ) и соотнесены в какой-то порядок поиска и доступа.

Как программист, я создал полноценный инструмент управления взаимоотношениями с клиентами, которым пользуется вся компания. Это включает в себя управление профилями клиентов, инструменты для отслеживания заказов и заданий, модули создания и управления заданиями / продажами и т. Д., А также любой файл, который необходим на уровне профиля клиента (водительские права, кредитный орган и т. Д.) Или на работе / Уровень продажи (контракты, голосовые подписи и т. д.) может быть загружен на сервер и расположен в иерархической структуре родительского / дочернего объекта, как в Windows Explorer или любой другой типичной модели управления файлами.

Структура выглядит так:

drivers_license
| - DL_123.jpg
voice_signatures
| - VS_123.wav
| - VS_4567.wav
контракты

Таким образом, файлы загружаются с использованием PHP и Apache и хранятся в файловой системе ОС. Во время загрузки определенная информация о файле (ах) сохраняется в базе данных MySQL. Некоторая информация хранится:

TABLE: FileUploads
FILEID
CustomerID (идентификатор клиента, которому принадлежит файл, у них всех есть это.)
JobID / SaleID (идентификатор связанной работы / продажи, если есть)
FileSize
FileType
UploadedDateTime
UploadedBy
FilePath (путь к каталогу, в котором хранится файл.)
FileName (текущее имя загруженного файла, комбинация CustomerID и JobID / SaleID, если применимо.)
FileDescription
OriginalFileName (оригинальное имя исходного файла при загрузке, включая расширение.)

Итак, как вы можете видеть, файл связан с базой данных по имени файла. Когда я хочу предоставить файлы клиентов для загрузки пользователю, все, что мне нужно сделать, это «SELECT * FROM FileUploads WHERE CustomerID = 123 ИЛИ JobID = 2345;» и это выведет все детали файла, которые мне требуются, и с помощью FilePath и FileName я могу предоставить ссылку для скачивания.

http ... server / FilePath / FileName

Существует ряд проблем с этим методом:

  1. Хранение файлов в этой среде «базы данных без сознания» означает, что целостность данных не сохраняется. Если запись удалена, файл также не может быть удален, или наоборот.
  2. Файлы разбросаны повсюду, на разных серверах, компьютерах и т. Д.
  3. Имя файла - это ЕДИНСТВЕННАЯ вещь, соответствующая двоичному файлу, базе данных, профилю клиента и записям клиента.

и т. Д. И т. Д. Существует так много причин, некоторые из которых описаны здесь: http://www.dreamwerx.net/site/article01. Также здесь есть интересная статья: sietch.net/ViewNewsItem.aspx?NewsItemID=124.

Итак, после долгих исследований я в значительной степени решил, что собираюсь сохранить ВСЕ эти файлы в базе данных, как BLOB или LONGBLOB, но есть еще много соображений, прежде чем я это сделаю.

Я знаю, что хранение их в базе данных является жизнеспособным вариантом, однако существует несколько способов их хранения.Я также знаю, что хранить их - это одно;корреляция и доступ к ним управляемым способом - это совсем другое.

Статья, представленная по этой ссылке: dreamwerx.net/site/article01, описывает способ разбиения загруженных двоичных файлов на куски по 64 КБ и сохранения каждого чанка с помощьюFileID, а затем потоковую передачу фактического двоичного файла клиенту с использованием заголовков.Это действительно крутая идея, так как она ослабляет давление на память серверов;вместо загрузки всего файла 100 МБ в ОЗУ и последующей отправки его клиенту, он делает это 64 КБ за раз.Я попробовал это (и обновил его сценарии), и это совершенно успешно, в очень маленькой рамке тестирования.

Так что, если вы согласны с тем, что этот метод является жизнеспособным, стабильным и надежным долгосрочным вариантомдля хранения умеренно больших файлов (от 1 КБ до пары сотен мегабайт) и большого количества этих файлов, дайте мне знать, какие у вас есть другие соображения или идеи.

Кроме того, я рассматриваю возможность получения текущего PHP "Управление файлами" PHPскрипт, который дает интерфейс для управления файлами, хранящимися в файловой системе, и преобразования его в файлы, хранящиеся в базе данных.Если уже есть какое-либо программное обеспечение, которое делает это, пожалуйста, дайте мне знать.

Я думаю, что я могу задать много вопросов, и вся информация там есть ^^, поэтому, пожалуйста, обсудите все аспекты этогои мы можем передавать идеи взад и вперед и учить друг друга.

Приветствия,

Quantico773

1 Ответ

37 голосов
/ 11 января 2011

Я работаю над большой программной системой, в которой реализованы оба механизма для хранения вложений и другого контента.Первая итерация системы сохраняла все данные в BLOB в БД.Я проклял это в то время.Как программист, я мог писать сторонние сценарии, чтобы немедленно работать с данными и изменять их всякий раз, когда захотел.

Заранее около 10 лет, и я все еще управляю тем же программным обеспечением, но архитектура изменилась, и он был написан суказатели файловой системы.Я проклинаю это сейчас и хочу, чтобы это вернулось в БД.У меня есть дополнительное преимущество, заключающееся в том, что я несколько лет работал над этим приложением в гораздо большей и большей степени, и я чувствую, что мое мнение теперь лучше образовано.Продвижение или системная миграция приложения требует обширных сценариев и копирования миллионов файлов.Однажды мы изменили ОС, и все указатели файлов имели неправильный разделитель каталогов, или имя сервера изменилось там, где находился файл, и нам пришлось написать и запланировать простые операторы обновления SQL с администратором базы данных на выходные, чтобы исправить это.Другая причина состоит в том, что файловая система и записи в БД не синхронизированы, почему это неясно, но после тысяч дней работы иногда нетранзакционные системы (файловая система и БД не используют транзакционный контекст) просто не синхронизируются.Иногда файлы таинственно пропадают.

Когда все это происходило в БД, миграция или продвижение среды были делом сброса и импорта БД.Изменения строк могут быть надлежащим образом проверены, все синхронизированные данные и журналы могут быть воспроизведены к моменту времени, если это необходимо.Конечно, БД становится большой, но это 2011 год, и это просто не проблема для баз данных.

Для чего стоит, у нас были некоторые подобные проблемы с большими буферами данных при потоковой передаче некоторых данных, но А) мыЕсли при использовании других инструментов мы можем перекачивать данные в байтовые буферы с помощью Input | OutputStreams в JDBC и B), мы написали хранимую процедуру, которая будет помещать BLOB-объект во временную таблицу и итеративно обслуживать фрагменты из временной таблицы.Прекрасно работает.

Мне все равно, по какой технической причине не помещает этот материал в БД, но намного проще управлять в консолидированнойЯ могу удвоить и утроить аппаратное обеспечение или сетку БД за время, потраченное консультантами и заказчиками за короткий промежуток времени на управление разрозненными файлами.


Обновление: не волнуйтесь, комментаторы, онипросто высказываю свое мнение по этому вопросу.

...