Загрузка файлов в базу данных - PullRequest
3 голосов
/ 11 ноября 2011

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

  1. Создайте структуру данных, которая оборачивает массив byte[], (двоично) сериализует его и отправляет вместе с данными; или

  2. Сначала отправьте оставшиеся данные, поймайте идентификатор записи и отправьте каждый файл отдельно (связав его с данным идентификатором);

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

Если бы вы столкнулись с этой проблемой, какой вариант вы бы выбрали? Если ни один из тех, что я изложил выше, какой тогда?

Редактировать: База данных расположена на удаленном сервере. Файлы могут быть произвольно большими, хотя я не ожидаю, что они будут больше, скажем, 1-2 МБ. Хранение файлов в месте, доступном как приложению, так и серверу базы данных, не вариант, поэтому я не могу просто отправить пути к файлам в базу данных (они действительно должны храниться в виде больших двоичных объектов в базе данных).

Ответы [ 2 ]

1 голос
/ 11 ноября 2011

Ваш первый план был отклонен из-за проблем с производительностью - возможно, это означает скорость передачи по сети?

Ваш альтернативный план состоит в том, чтобы отправлять файлы по отдельности, а затем связывать их вместе на вашем сервере. Это хороший план, но вы хотите убедиться, что все файлы загружены и зафиксированы в одной транзакции. Исходя из этого, ваш сервер не может ответить сигналом успеха, пока не получит все файлы и не подтвердит их.

Таким образом, ваш второй сценарий требует, чтобы в транзакции было загружено одинаковое количество данных. Как тогда он сможет работать лучше?

Фактически, любой возможный дизайн, который вы можете придумать - при условии, что файлы должны быть получены в рамках одной транзакции, - будет иметь ту же «проблему производительности».

Возможно, вы понимаете «транзакцию» иначе, чем я, но обычно вы не можете пойти и использовать первоначально предоставленные «оставшиеся данные», пока транзакция не будет завершена. Я думаю, что ваша проблема связана с необходимостью «единой транзакции» вашей системы, а не с узким местом сети.

0 голосов
/ 11 ноября 2011

Мы используем два разных сценария для этого в зависимости от наших потребностей на данный момент и ожидаемого размера файлов:

1) Мы передаем файлы в принимающую систему и кэшируем их в хорошо известномместоположение в принимающей системе (то есть временный каталог, использующий GUID для имени файла).Это может быть сделано асинхронно для повышения производительности.Вам необходимо иметь доступную ссылку (например, GUID) в записи, связанной с файлом, чтобы принимающая система могла найти файл.Поскольку запись записывается в базу данных, мы передаем содержимое файла в параметр (параметр хранимой процедуры), чтобы он находился в памяти в течение кратчайшего периода времени.

2) Если файлы относительномаленький, мы будем передавать их в байтовый массив в записи.Это, безусловно, проще всего реализовать, но если ваши файлы имеют большой размер, вы теряете некоторый контроль над производительностью при отправке своих записей «по проводам».

...