0
Требуется хранить большое кол-во файлов на диске
Started by Ilg, Jun 25 2009 10:42 PM
11 replies to this topic
#1
Posted 25 June 2009 - 10:42 PM
Собсно сабж, куча файлов, которые загружаются на сервер. хранить в одной директории нецелесообразно. вариант хранения файлов в БД исключается. какие предлагаете варианты решения проблемы, а именно какова логика разнесения файлов по поддиректориям?
гуглить и предлагать не надо, только из собственной практики
гуглить и предлагать не надо, только из собственной практики
#2
Posted 25 June 2009 - 10:56 PM
Ну, зависит от того, что за файлы и каково их предназначение. Если это портал а ля softsearch.ru или фотохранилище - хранить лучше по дате. Всё остальное - по тематике. Имхо, конечно. Я храню по тематике.
#3
Posted 25 June 2009 - 11:05 PM
допустим, фото хранилище.
то есть у тебя на один раздел одна директория без вложенной структуры?
по дате тоже не оптимально, могут быть дни, когда будет загружено несколько тысяч файлов, например через Bulk upload. кто нить решит за один раз свой локальный архив загрузить допустим.
забыл приписать, речь идет о хранении содержимого на одном сервере.
то есть у тебя на один раздел одна директория без вложенной структуры?
по дате тоже не оптимально, могут быть дни, когда будет загружено несколько тысяч файлов, например через Bulk upload. кто нить решит за один раз свой локальный архив загрузить допустим.
забыл приписать, речь идет о хранении содержимого на одном сервере.
#4
Posted 26 June 2009 - 05:36 AM
Можно установить лимит файлов на директорию и давать директориям случайные имена. К примеру
./photos/26092009/xf39g0a/photo_01.jpg
...
./photos/26092009/xf39g0a/photo_1000.jpg
./photos/26092009/xf39g0a/photo_01.jpg
...
./photos/26092009/xf39g0a/photo_1000.jpg
#5
Posted 26 June 2009 - 07:57 AM
опиши подробнее если давать случайные имена, не получится ли что у тебя в каждой директории будет по одному файлу?
#6
Posted 26 June 2009 - 04:42 PM
В теории - возможно. Но если у тебя действительно большой сервис такого быть не должно. Ну, вот к примеру, ты высчитываешь, что в папке не может быть более 1000 файлов (или папка не может весить больше 1 Гб). Если одно из условий true - создаём в сегодняшей дате ещё одну папку со случайным именем.
Либо можно ещё извратиться и хранить вот так:
./photos/26062009/0000/
./photos/26062009/0030/
Т.е каждые 3 часа менять папку Хотя это всё теория, потому что мне хватало простого метода и извращаться не требовалось. Каждый случай уникален. А что такое ты разрабатываешь?
Либо можно ещё извратиться и хранить вот так:
./photos/26062009/0000/
./photos/26062009/0030/
Т.е каждые 3 часа менять папку Хотя это всё теория, потому что мне хватало простого метода и извращаться не требовалось. Каждый случай уникален. А что такое ты разрабатываешь?
#7
Posted 26 June 2009 - 05:20 PM
да ничего особенного, контент провайдер, просто хотел узнать кто что скажет, еще Чарли зашел бы сюда когда нибудь ))
#8
Posted 26 June 2009 - 06:04 PM
А сам-то как думаешь?
#9
Posted 26 June 2009 - 06:46 PM
Elkaz,
ты о чем? о сабже или о чарли?
ты о чем? о сабже или о чарли?
#10
Posted 26 June 2009 - 09:02 PM
О сабже конечно
#11
Posted 26 June 2009 - 10:08 PM
я вычисляю хеш по формуле
for (char c : filename.toCharArray()) {
hash += (int) c ^ (int) (Math.random() * 26);
}
char letter = (char) (hash % size);
в моей задаче подходит именно random генерация, потому что я не хочу детерминированного результата, в таком случае все файлы с одинаковым именем попадут в одну и ту же директорию. функцию я применяю 3 раза подряд, получая 3 символа, символы объединяю в путь, получаю что то типа /a/b/c/filename.
3х уровней достаточно для хранения 1 миллиона записей с относительно равномерным распределением по директориям, в каждой будет находиться где то 60 файлов. соотв, 1000 файлов в директории ~ 20 миллионов файлов (это не для моего приложения). для 100-700К файлов можно обойтись двумя уровнями.
можно немного поменять функцию, вместо рандома применять метод вычисления хеш кода, тока потом надо взять остаток от деления на 26, чтобы получить букву. тогда результат будет постоянный, можно функцию применять к increment primary key (правда надо удачно подобрать функцию изза инкремента). в таком случае можно не хранить в базе путь, и по коду определить путь в момент запроса файла (все зависит от задачи). опять же в моем случае это не нужно, проще путь хранить.
for (char c : filename.toCharArray()) {
hash += (int) c ^ (int) (Math.random() * 26);
}
char letter = (char) (hash % size);
в моей задаче подходит именно random генерация, потому что я не хочу детерминированного результата, в таком случае все файлы с одинаковым именем попадут в одну и ту же директорию. функцию я применяю 3 раза подряд, получая 3 символа, символы объединяю в путь, получаю что то типа /a/b/c/filename.
3х уровней достаточно для хранения 1 миллиона записей с относительно равномерным распределением по директориям, в каждой будет находиться где то 60 файлов. соотв, 1000 файлов в директории ~ 20 миллионов файлов (это не для моего приложения). для 100-700К файлов можно обойтись двумя уровнями.
можно немного поменять функцию, вместо рандома применять метод вычисления хеш кода, тока потом надо взять остаток от деления на 26, чтобы получить букву. тогда результат будет постоянный, можно функцию применять к increment primary key (правда надо удачно подобрать функцию изза инкремента). в таком случае можно не хранить в базе путь, и по коду определить путь в момент запроса файла (все зависит от задачи). опять же в моем случае это не нужно, проще путь хранить.
#12
Posted 29 June 2009 - 05:24 AM
в одном проекте пришлось писать такую функцию..
язык: C#
язык: C#
Код
private static string GenerateTempPhotoName(int userID, int photoID)
{
string result = "";
int step1 = userID + photoID;
int step2 = step1 * 2;
int step3 = step1 / 3;
int step4 = step1 + 5;
int step5 = step1 * 7;
int step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = step6.ToString();
step1 = step6 + 7;
step2 = step6 / 2;
step3 = step2 * 3;
step4 = step3 / 7;
step5 = step4 * 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = string.Format("{0}{1}", step6, result);
step1 = step6 + 23;
step2 = step1 / 2;
step3 = step2 * 3;
step4 = step3 / 7;
step5 = step4 * 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = string.Format("{0}{1}", result, step6);
step1 = step6 + 117;
step2 = step1 / 2;
step3 = step2 * 3;
step4 = step3 / 7;
step5 = step4 * 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = string.Format("{0}{1}", result, step6);
step1 = step6 + 113;
step2 = step1 / 2;
step3 = step2 * 3;
step4 = step3 + 7;
step5 = step4 - 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
return string.Format("{0}_{1}{2}{3}{4}{5}{6}{7}{8}", photoID, step6, result.Length, result, step4, step3, step5, step2, step1);
}
{
string result = "";
int step1 = userID + photoID;
int step2 = step1 * 2;
int step3 = step1 / 3;
int step4 = step1 + 5;
int step5 = step1 * 7;
int step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = step6.ToString();
step1 = step6 + 7;
step2 = step6 / 2;
step3 = step2 * 3;
step4 = step3 / 7;
step5 = step4 * 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = string.Format("{0}{1}", step6, result);
step1 = step6 + 23;
step2 = step1 / 2;
step3 = step2 * 3;
step4 = step3 / 7;
step5 = step4 * 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = string.Format("{0}{1}", result, step6);
step1 = step6 + 117;
step2 = step1 / 2;
step3 = step2 * 3;
step4 = step3 / 7;
step5 = step4 * 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
result = string.Format("{0}{1}", result, step6);
step1 = step6 + 113;
step2 = step1 / 2;
step3 = step2 * 3;
step4 = step3 + 7;
step5 = step4 - 5;
step6 = (step1 + step2 + step3 + step4 + step5) / 5;
return string.Format("{0}_{1}{2}{3}{4}{5}{6}{7}{8}", photoID, step6, result.Length, result, step4, step3, step5, step2, step1);
}
0 user(s) are reading this topic
members, guests, anonymous users