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


79

У меня есть проект, который будет генерировать огромное количество изображений. Около 1 000 000 для начала. Они не являются большими изображениями, поэтому при запуске я буду хранить их все на одной машине.

Как вы рекомендуете хранить эти изображения эффективно? (Файловая система NTFS в настоящее время)

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

что будет лучше схема именования:

a / b / c / 0 ... z / z / z / 999

или же

A / B / C / 000 ... Z / Z / Z / 999

есть идеи по этому поводу?


1
Они привязаны к конкретным пользователям или просто общие? Они сгруппированы каким-либо образом?

только общий. куча изображений, сгенерированных каким-то техническим оборудованием. я называю их инкрементными от 1 до только для того, чтобы иметь представление о временной отсрочке.
s.mihai

как они собираются быть использованы / доступны? через сделанное на заказ приложение или как?
голубь


1
:)) да ... 1 мил. порно картинки :))
s.mihai

Ответы:


73

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

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

 File path = generatePathFromSequenceNumber(sequenceNumber);

Проще справиться, если вам нужно как-то изменить структуру каталогов. Может быть, вам нужно переместить изображения в другое место, может быть, вам не хватает места и вы начинаете хранить некоторые изображения на диске A, а некоторые на диске B и т. Д. Изменить одну функцию проще, чем изменить пути в базе данных. ,

Я бы использовал этот вид алгоритма для генерации структуры каталогов:

  1. Сначала добавьте порядковый номер с начальными нулями, пока у вас не будет как минимум 12-значной строки. Это имя для вашего файла. Вы можете добавить суффикс:
    • 12345 -> 000000012345.jpg
  2. Затем разбейте строку на 2 или 3 символьных блока, где каждый блок обозначает уровень каталога. Иметь фиксированное количество уровней каталогов (например, 3):
    • 000000012345 -> 000/000/012
  3. Сохраните файл в сгенерированном каталоге:
    • Таким образом, полный путь к файлу и имя файла для файла с идентификатором последовательности 123является 000/000/012/00000000012345.jpg
    • Для файла с идентификатором последовательности 12345678901234путь будет123/456/789/12345678901234.jpg

Некоторые вещи, которые следует учитывать относительно структуры каталогов и хранения файлов:

  • Вышеприведенный алгоритм дает вам систему, в которой каждый конечный каталог имеет максимум 1000 файлов (если у вас меньше 1 000 000 000 000 файлов)
  • Может быть ограничение на количество файлов и подкаталогов, которые может содержать каталог, например, файловая система ext3 в Linux имеет ограничение в 31998 подкаталогов на один каталог.
  • Обычные инструменты (WinZip, Windows Explorer, командная строка, оболочка bash и т. Д.) Могут работать не очень хорошо, если у вас есть большое количество файлов в каталоге (> 1000)
  • Структура каталогов сама по себе займет некоторое дисковое пространство, поэтому вам не нужно слишком много каталогов.
  • С приведенной выше структурой вы всегда можете найти правильный путь к файлу изображения, просто взглянув на имя файла, если вам случится испортить структуру каталогов.
  • Если вам нужен доступ к файлам с нескольких компьютеров, рассмотрите возможность совместного использования файлов через сетевую файловую систему.
  • Приведенная выше структура каталогов не будет работать, если вы удалите много файлов. Это оставляет «дыры» в структуре каталогов. Но так как вы не удаляете файлы, все должно быть в порядке.

1
очень интересно! разделив имя файла ... я не думал об этом. Я предполагаю, что это элегантный способ сделать это: -?
s.mihai

37
Использование хэша (такого как MD5) в качестве имени файла, а также распределения каталогов, будет работать. Целостность файлов будет не только дополнительным преимуществом схемы именования (легко проверяется), но вы будете иметь достаточно равномерное распределение по всей иерархии каталогов. Поэтому, если у вас есть файл с именем "f6a5b1236dbba1647257cc4646308326.jpg", вы должны сохранить его в "/ f / 6" (или настолько глубоко, насколько вам нужно). Глубина 2 уровня дает 256 каталогов, или чуть менее 4000 файлов на каталог для начальных 1м файлов. Также было бы очень легко автоматизировать перераспределение по более глубокой схеме.

+1 Я только заметил, что этот ответ был похож на тот, который я только что опубликовал.
3dinfluence

1
Я определенно согласен с использованием файловой системы и созданием искусственного идентификатора для «разрезания» по именам папок. Но вы также должны попытаться получить случайное распределение идентификаторов, то есть не использовать порядковый номер. Это позволит вам иметь более сбалансированное дерево папок. Кроме того, при случайном распределении вы можете легко разделить дерево по нескольким файловым системам. Я бы также использовал SAN на основе ZFS с включенным режимом дедупликации и редким томом для каждой файловой системы. Вы все еще можете использовать NTFS, используя iSCSI для доступа к SAN.
Майкл Диллон

Если перейти к шагу 2 справа налево, файлы распределяются равномерно. Также вам не нужно беспокоиться о том, что вы не заполняете достаточное количество нулей, поскольку вы можете неограниченное количество файлов
ropo

31

Я собираюсь поставить свои 2 цента на один отрицательный совет: не ходите с базой данных.

Я работаю с базами данных для хранения изображений в течение многих лет: большие (1 мегабайта) файлы, часто изменяемые, несколько версий файла, доступ к которым осуществляется достаточно часто. Проблемы с базой данных, с которыми вы сталкиваетесь при хранении больших файлов, чрезвычайно утомительны, проблемы с записью и транзакциями запутаны, и вы сталкиваетесь с проблемами блокировки, которые могут привести к серьезным авариям поездов. У меня есть еще практика в написании сценариев DBCC и восстановление таблиц из резервных копий , чем любой нормальный человек должен когда - либо иметь.

Большинство новых систем, с которыми я работал, перенесли хранилище файлов в файловую систему и полагались на базы данных только для индексации. Файловые системы спроектированы таким образом, чтобы справляться с подобными злоупотреблениями, их гораздо проще расширять, и вы редко теряете всю файловую систему, если одна запись повреждена.


да. записка принята!
s.mihai

5
Вы смотрели на тип данных FILESTREAM в SQL 2008? Это нечто среднее между базой данных и хранилищем файловой системы.
NotMe

+1 при использовании файлового сервера, а не базы данных, поскольку вы выполняете быстрые и редкие операции ввода-вывода.

Что делать, если вы просто храните несколько сотен документов или рисунков на базу данных - какие-либо недостатки использования базы данных для хранения?
Звуковой сигнал

1
+1 ... файловая система в любом случае является своего рода «базой данных» (наверняка, ntfs), так зачем делать ее слишком сложной.
Акира

12

Я думаю, что большинство сайтов, которые имеют дело с этим, используют какой-то хэш, чтобы обеспечить равномерное распределение файлов в папках.

Допустим, у вас есть хеш файла, который выглядит примерно так: 515d7eab9c29349e0cde90381ee8f810
вы можете хранить его в следующем месте и использовать сколько угодно глубоких уровней, чтобы количество файлов в каждой папке было низким.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

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


2
Git использует похожий подход: git-scm.com/book/en/v2/Git-Internals-Git-Objects (чтобы поддержать этот ответ)
aexl

11

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

Предполагая, что у вас есть контроль над именами файлов, я бы разделил их на уровне 1000 с на каталог. Чем больше уровней каталогов вы добавляете, тем больше инодов вы записываете, так что здесь есть push-pull.

Например,

/ Корень / [0-99] / [0-99] / имя_файла

Обратите внимание, что http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx содержит более подробную информацию о настройке NTFS. В частности: «Если вы используете большое количество файлов в папке NTFS (300 000 или более), отключите генерацию коротких имен файлов для повышения производительности, особенно если первые шесть символов длинных имен файлов похожи».

Вам также следует обратить внимание на отключение ненужных функций файловой системы (например, время последнего доступа). http://www.pctools.com/guides/registry/detail/50/


3
+1 за отключение 8.3 генерации имени файла и времени последнего доступа; это было первое, что пришло в голову, когда я прочитал «огромное количество [файлов]» и «NTFS» (Windows).
ограбить

ссылка вниз ........................
Pacerier

7

Что бы вы ни делали, не храните их все в одном каталоге.

В зависимости от распределения имен этих изображений вы можете создать структуру каталогов, в которой у вас будут однобуквенные папки верхнего уровня, где у вас будет другой набор подпапок для 2-й буквы изображений и т. Д.

Так:

Папка img\a\b\c\d\e\f\g\будет содержать изображения, начинающиеся с abcdefg и т. Д.

Вы можете ввести свою собственную необходимую глубину.

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


\ a \ b \ c \ d \ e \ f \ я делаю сейчас, я думал, что есть мудрый способ сделать это.
s.mihai

1
Это общепринятое решение о том, как их физически хранить. Очевидно, что генерация URL-адресов изображений - это то, что можно легко сделать динамически на основе имени файла изображения. Кроме того, чтобы обслужить их, вы даже можете добавить поддомен img-a, img-b на сервер изображений, если хотите, чтобы ускорить время загрузки.

2
И +1 за "не хранить их все в одном каталоге". Я поддерживаю устаревшую систему, которая поместила более 47000 файлов на сервер в одну папку, и Explorer занимает около минуты, чтобы открыть папку.
Марк Рэнсом

5
Выполнение \ b \ c \ d \ e \ f \ g делает структуру каталогов очень глубокой, и каждый каталог содержит всего несколько файлов. Лучше использовать более одной буквы на уровень каталога, например, ab \ cd \ ef \ или abc \ def \. Каталоги также занимают место на диске, поэтому вам не нужно их слишком много.
Юха Сыряля

2
Мне нужно было поддерживать приложение, в котором было более 4 миллионов файлов в одном каталоге; он работал на удивление хорошо, но вы НИКОГДА не могли получить проводник, чтобы открыть папку, он постоянно сортировал новые дополнения. +1 за способность NTFS справиться с этим, не умирая.
SqlACID

5

Я бы сохранил их в файловой системе, но это зависит от того, насколько быстро будет расти количество файлов. Эти файлы размещены в Интернете? Сколько пользователей будет иметь доступ к этим файлам? На эти вопросы нужно ответить, прежде чем я смогу дать вам лучшую рекомендацию. Я бы также посмотрел на Haystack из Facebook, у них есть очень хорошее решение для хранения и обработки изображений.

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


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

меня интересует мнение программиста, чтобы я не задумывался об этом слишком много
s.mihai

Поэтому, если вам не нужен быстрый доступ, Haystack, вероятно, не для вас. Использование каталогов для разделов, на мой взгляд, самое простое решение.
Лукаш

5

У нас есть система фотомагазинов с 4 миллионами изображений. Мы используем базу данных только для метаданных, и все изображения хранятся в файловой системе с использованием системы с обратными именами, где имена папок генерируются из последней цифры файла, last-1 и т. Д. Например: 000001234.jpg хранится в структуре каталогов, например 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

Эта схема очень хорошо работает с индексом идентичности в базе данных, потому что она равномерно заполняет всю структуру каталогов.


4

Быстрый момент: вам не нужно хранить путь к файлу в вашей БД. Вы можете просто сохранить числовое значение, если ваши файлы названы так, как вы описываете. Затем, используя одну из четко определенных схем хранения, которые уже обсуждались, вы можете получить индекс в виде числа и очень быстро найти файл, пройдя через структуру каталогов.


: -? хороший быстрый момент. просто сейчас у меня нет алгоритма генерации пути.
s.mihai


4

Ваши изображения должны быть названы уникально? Может ли процесс, который генерирует эти изображения, создавать одно и то же имя файла более одного раза? Трудно сказать, не зная, какое устройство создает имя файла, но сказать, что устройство «перезагружено», и после перезапуска оно начинает называть изображения так же, как в прошлый раз, когда оно «сбрасывалось» - если это такая проблема.

Кроме того, вы говорите, что вы получите 1 миллион изображений за месяц. Как насчет этого? Как быстро эти изображения будут продолжать заполнять файловую систему? Будут ли они завершаться в какой-то момент и выровняться примерно на 1 млн. ОБЩИХ изображений или оно будет расти и расти месяц за месяцем?

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

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

Месяц, год, даже день хорош для изображений типа безопасности. Не уверен, что это то, что вы делаете, но я сделал это с домашней камерой безопасности, которая делала снимки каждые 10 секунд ... Таким образом, ваше приложение может переходить к определенному времени или даже диапазону, в котором вы можете подумать, что изображение было сгенерировано. , Или вместо года, месяца - есть ли какое-то другое «значение», которое может быть получено из самого файла изображения? Некоторые другие дескрипторы, кроме примера даты, который я дал?

Я бы не стал хранить двоичные данные в БД. Никогда не было хорошей производительности / удачи с такими вещами. Не могу себе представить, что это хорошо работает с 1 миллионом изображений. Я хотел бы сохранить имя файла, и это все. Если они все будут JPG, тогда даже не храните расширение. Я хотел бы создать контрольную таблицу, в которой хранится указатель на сервер файла, диск, путь и т. Д. Таким образом, вы можете переместить эти изображения в другое поле и по-прежнему находить их. Вам нужно пометить тегами ваши изображения? Если это так, то вы захотите построить соответствующие таблицы, которые позволяют такого рода маркировки.

Возможно, вы / другие обсуждали эти идеи, когда я отвечал. Надеюсь, это поможет.


1. Все файлы будут иметь уникальные имена. 2. Система будет расти и расти, сначала она получит около 1 миллиона изображений, а затем будет расти со скоростью пару десятков тысяч в месяц. 3. когда-нибудь в будущем произойдет маркировка файлов, поэтому я хочу сохранить идентификационные данные в БД.
s.mihai

3

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

Мое решение, основанное на этом использовании, заключалось в постепенном сжатии изображений в сжатые файлы. Изображения представляют собой файлы JPG, каждый размером около 20 КБ и не сжимают сильно, поэтому схема сжатия ZIP отсутствует. Это делается просто для объединения их в одну запись файловой системы, что значительно помогает NTFS с точки зрения скорости, когда речь идет о перемещении их с диска на диск или просмотре списка файлов.

Изображения старше суток объединяются в «ежедневный» почтовый индекс; молнии старше месяца объединяются в соответствующие «месячные» молнии; и, наконец, ничего больше года больше не нужно и, следовательно, удаляется.

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

Я понимаю, что это, вероятно, не связано с вашими конкретными деталями, но я думал, что поделюсь.


2

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

  • Несколько изображений генерируются каждый день: Year/Month/Day/Hour_Minute_Second.png
  • Пара в месяц: Year/Month/Day_Hour_Minute_Second.png

и т.д. Вы понимаете мою точку зрения ... =)


они не генерируются непрерывно с течением времени, поэтому некоторые папки становятся толстыми, а другие остаются ... тонкими :))
s.mihai

Ну, очевидно, вам не нужно создавать каждую папку только потому, что вы следуете этой схеме. Вы могли бы даже Year/Month/Day/Hour/Minute- решить, сколько уровней папок вам нужно, в зависимости от того, как часто изображения генерируются, когда скорость самая высокая - и тогда просто не создавать папки, которые были бы оставлены пустыми.
Томас Ашан

2

Я был бы склонен создать структуру папок на основе даты, например, \ year \ month \ day, и использовать временные метки для имен файлов. При необходимости временные метки могут иметь дополнительный компонент счетчика, если изображения должны создаваться так быстро, что их может быть больше одного в течение миллисекунды. Благодаря использованию наиболее значимой или наименее значимой последовательности для сортировки имен поиск и обслуживание становятся проще простого. например, hhmmssmm [seq] .jpg


2

Вы рассматриваете возможность аварийного восстановления?

Некоторые из предложенных здесь решений приводят к искажению имени файла (например, если физический файл был перемещен, вы потеряете информацию о том, какой это файл на самом деле). Я рекомендую сохранить уникальное физическое имя файла, чтобы, если ваш основной список расположений файлов был поврежден, вы могли восстановить его с помощью небольшой оболочки, например, powershell, script;)

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

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

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

При необходимости рассмотрите возможность использования CDN, например Amazon S3.


2

Хотя я не обслуживал изображения в таком масштабе, ранее я написал небольшое приложение для галереи, обслуживающее ~ 25 тыс. Изображений на машине с частотой 400 МГц. 512 МБ ОЗУ или около того. Некоторые переживания;

  • Избегайте реляционных баз данных любой ценой; В то время как базы данных, без сомнения, умны в обработке данных, они не предназначены для такого использования (у нас есть специализированные, иерархические базы данных значения ключа для так называемых файловых систем ). Хотя у меня нет ничего, кроме догадки, я бы поспорил, что кеш БД уходит в окно, если вы кидаете в него действительно большие капли. В то время как моё доступное оборудование было в самом начале, полное отсутствие обращения к БД при поиске изображения дало скорость на порядок выше.

  • Исследуйте, как ведет себя файловая система; в ext3 (или это был ext2 в то время - не помню) предел способности эффективно искать подкаталоги и файлы был около отметки 256; Таким образом, имея только столько файлов и папок в любой папке. Опять заметное ускорение. Хотя я не знаю о NTFS, такие вещи, как XFS (которая, насколько я помню, использует B-деревья), чрезвычайно быстры, просто потому, что они могут выполнять поиск очень быстро.

  • Распределить данные равномерно; когда я экспериментировал с вышеизложенным, я пытался распределить данные равномерно по всем каталогам (я сделал MD5 URL-адреса и использовал его для каталогов; /1a/2b/1a2b...f.jpg). Таким образом, требуется больше времени, чтобы достичь любого ограничения производительности (и кэш файловой системы в любом случае становится пустым при таких больших наборах данных). (наоборот, вы можете захотеть увидеть, где находятся ограничения в начале; затем вы хотите выбросить все в первый доступный каталог.


2

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

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

Это приведет к тому, что путь будет:

/172/029/cat.gif

Затем вы можете найти cat.gifв структуре каталогов, воспроизведя алгоритм.

Использование HEX в качестве имен каталогов будет так же просто, как преобразование intзначений:

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

В результате чего:

/AC/1D/cat.gif

Я написал статью об этом несколько лет назад и недавно переместил ее в Medium. В нем есть еще несколько деталей и пример кода: Хеширование имени файла: Создание хешированной структуры каталогов . Надеюсь это поможет!


Мы храним 1,8 миллиарда товаров, используя что-то подобное. Это работает хорошо. Используйте быстрый хеш, с низким уровнем коллизий, и все готово.
CVVS


1

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

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


1

Я просто запустил тест на zfs, потому что я люблю zfs, и у меня был раздел на 500 гигабайт, на котором у меня было сжатие. Я написал скрипт, который генерировал файлы размером 50-100 тыс. И помещал их во вложенные каталоги 1/2/3/4/5/6/7/8 (5-8 уровней в глубину) и позволил ему работать, я думаю, 1 неделю. (это был не очень хороший сценарий.) Он заполнил диск и в итоге получил около 25 миллионов файлов или около того. Доступ к любому файлу с известным путем был мгновенным. Перечисление любого каталога с известным путем было мгновенным.

Однако подсчет списка файлов (через find) занял 68 часов.

Я также провел тест, поместив множество файлов в один каталог. Я получил до 3,7 миллионов файлов в одном каталоге, прежде чем я остановился. Перечисление каталога для подсчета заняло около 5 минут. Удаление всех файлов в этом каталоге заняло 20 часов. Но поиск и доступ к любому файлу был мгновенным.


1

Я вижу другие упоминания о базе данных, но не вижу упоминаний об этом в вашем посте. В любом случае, мое мнение по этому конкретному вопросу таково: либо придерживайтесь базы данных, либо файловой системы. Если вам нужно смешать два, будьте осторожны с этим. Все становится сложнее. Но вам, возможно, придется. Хранение миллиона фотографий в базе данных не самая лучшая идея.

Вас может заинтересовать следующая спецификация, большинство цифровых камер следуют ей для управления хранением файлов: https://en.wikipedia.org/wiki/Camera_Image_File_Format

По сути, создается папка, например, 000OLYMPUSи фотографии добавляются в эту папку (например DSC0000.RAW). Когда счетчик имени файла достигает, DSC9999.RAWсоздается новая папка ( 001OLYMPUS) и изображение добавляется снова, сбрасывая счетчик, возможно, с другим префиксом (например:) P_0000.RAW.

В качестве альтернативы вы также можете создавать папки на основе частей имени файла (уже упоминалось несколько раз). Например, если ваша фотография названа IMG_A83743.JPG, сохраните ее в IMG_\A8\3\IMG_A83743.JPG. Его сложнее реализовать, но он облегчит поиск ваших файлов.

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


0

Возможно, вы захотите взглянуть на ZFS (файловая система, менеджер томов от Sun). С уважением,


0

Чистый способ создать путь из большого числа - легко преобразовать его в гекс, а затем разделить!

например , 1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

Хранить и загружать:

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

Полные исходные коды: https://github.com/acrobit/AcroFS


-1

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

Использование менеджера баз данных, безусловно, лучший вариант; простой, например, BDB или GDBM; даже родственная СУБД, такая как MySQL, будет лучше. Только ленивые люди, которые не понимают файловые системы и базы данных (например, те, кто отклоняет транзакции), склонны использовать файловые системы в качестве баз данных (или, реже, наоборот).


-2

Как насчет базы данных с таблицей, содержащей идентификатор и большой двоичный объект для хранения изображения? Затем вы можете добавлять новые таблицы, когда хотите связать больше элементов данных с фотографией.

Если вы ожидаете масштабирования, почему бы не масштабировать сейчас? Вы сэкономите время как сейчас, так и позже IMO. Реализуйте слой базы данных один раз, с чего довольно легко начать. Или реализуйте что-то с помощью папок и имен файлов и бла-бла-бла, а затем переключитесь на что-то другое, когда вы начнете взрывать MAX_PATH.


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

1
И есть много утилит для работы с файлами и файловыми системами, и совсем немного для работы с файлами в базе данных.
Марк Рэнсом

2
О Боже, нет. Пожалуйста, не используйте базу данных в качестве большого хранилища больших двоичных объектов.
Нил Н

Ик. Не знал, что базы данных (все еще?) Имеют так много проблем с BLOB.

Как может такое плохое решение, у которого есть так много комментариев, все еще иметь +1? не в обиду OP (я вижу, что он пришел от SO), но кнопка понижения здесь по причине!
Марк Хендерсон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.