Задать вопрос
Quber
@Quber
PHP Team lead

1 папка и 10 000 картинок или 10 000 папок и по одной картинке в каждой?

Разрабатывается сайт. В каком случае производительность будет выше - укладывать каждую картинку в отдельную папку (по id) или создать одну папку и складывать туда все картинки?
  • Вопрос задан
  • 10778 просмотров
Подписаться 35 Оценить 1 комментарий
Решения вопроса 2
хорошая практика, применяющаяся много где, например у Microsoft
вычисляем md5 у файла - 2274facdbca56499fe397344c633e25a
файл кладем в папку avatars/227/4fa/cdb/2274facdbca56499fe397344c633e25a.jpg
Ответ написан
Поддерживаю тех, кто сказал искать золотую середину. не вздумайте в одной папке делать более 1000 файлов или папок. Без разницы как осуществляется к ним доступ (по урл или ftp)!

Лично у меня миллионы картинок разбиты почти как советовали выше:
2274facdbca56499fe397344c633e25a.jpg лежит в 2/2/7/2274facdbca56499fe397344c633e25a.jpg
При такой структуре получаем не более 16ти папок в каждой папке.
Ответ написан
Пригласить эксперта
Ответы на вопрос 7
miraage
@miraage
Старый прогер
Вам определенно нужен jQuery.
Ответ написан
PafNutY
@PafNutY
Люблю кодить в своё удовольствие
Зависит от того как будет осуществляться доступ. Если только чтение по url без перебора - можно сложить в одну папку, но такие случаи редки, зайдёте в папку через ftp и будете огорчены сообщением об ошибке чтения.

Если есть возможность узнать к примеру дату загрузки/добавления картинки, то лучше конечно складывать по папкам, к примеру /год/месяц/
за месяц уж точно не накопится 10 000 картинок))

В любом случаи удобнее держать небольшое кол-во картинок в отдельных папках.
Ответ написан
@IceJOKER
Web/Android developer
для аватара что ли?)
думаю лучше в одной папке собрать всю кучу, потому что доступ к картинке идет через прямой url и там уже не важно сколько картинок в папке, а если идет перебор файлов, то конечно лучше второй вариант.
и можно использовать второй вариант(папок куча, фотка одна) , чтоб в дальнейшем была возможность в эту папку класть не только одну фотку.

все зависит от случая.
Ответ написан
viktorvsk
@viktorvsk
Если прямо отвечать на вопрос, то я думаю дела обстоят так (если ошибаюсь, поправьте):
1) Если в базе у вас хранится путь к картинке, то по производительности абсолютно не важно, это users/user_10000/avatar.png или users/avatar_10000.png
2) Каждая созданная директория - это накладные расходы (на большинстве файловых систем около 4 КБ, как я понимаю)
3) Фрагментирование здесь не играет роли, так как сервер обычно на юниксе, так что ничего страшного (вот тут не уверен)
Ответ написан
Комментировать
Лучше - золотая середина: 100 папок по 100 картинок в каждой.
Папка - это читай тот же файл. Если в директории слишком много файлов - начинаются тормоза. Поэтому лучше разбивать все так, чтобы файлы были в более-менее уникальных папках, но в то же время папок этих было не сильно много. Например, как предложили выше, добавлять папки с названием даты (при чем это должно быть 3 уровня папок - для года, для месяца и для даты).
Ответ написан
@maxxxixxxx
Предлагаю взять готовый класс отсюда

bablogon.net/view.php?p=151

класс в папке с классами

передаем классу id и класс формирует деревовидную структуру, так же можно указать число фойлов в папке и число ветвей

получить адрес на файл элементарно, нужно знать только его id

с папками тоже самое

<?php
/**
 * MVCPHP Framework
 * 
 * @link http://mvcphp.ru/
 * 
 */

/**
 * Класс загрузки
 * 
 */
class Upload {
    
    public $id;
    private $upload_dir;
    private $max_file_count;
    private $branches;

    public function __construct(array $param=array()) {
        $def_param=array('upload_dir'=>Q_PATH.'/uploads/','max_file_count'=>1000,'branches'=>2,'pattern'=>'');
        $upload_param=Functions::arr_union($def_param,$param);
        $this->upload_dir=$upload_param['upload_dir'];
        $this->max_file_count=$upload_param['max_file_count'];
        $this->branches=$upload_param['branches'];
        //сложность надумана, все зависит от инодов df -i и tune2fs -l /dev/hda1 и df -Ti
        switch($upload_param['pattern']) {
            case 'bigint':
                $this->max_file_count=512;
                $this->branches=6;
            break;
            case 'int':
                $this->max_file_count=216;
                $this->branches=3;
            break;
            case 'mediumint':
                $this->max_file_count=204;
                $this->branches=2;
            break;
            case 'smallint':
                $this->max_file_count=182;
                $this->branches=1;
            break;
        }
        $this->del_id();
    }
    
    public function set_id($id) {
        $this->id=$id;
    }
	
    public function del_id() {
        $this->id=0;
    }
    
    public function find_upload($url) {
        if(is_file($url)) {
            return true;
        }
        else {
            return false;
        }
    }
    
    public function get_upload($id,$fl) {
        $this->set_id($id);
        for($i=$this->branches;$i>=1;$i--) {
            $dir=ceil($this->id/pow($this->max_file_count,$i))%$this->max_file_count;
            $dir_file_arr[]=$dir>0?$dir:$this->max_file_count;
        }
        $dir_file_str=implode("/", $dir_file_arr);
        return $this->upload_dir.$dir_file_str.'/'.$this->id.$fl;
    }
    
    public function put_upload($id,$fl,$data) {
        $this->set_id($id);
        for($i=$this->branches;$i>=1;$i--) {
            $dir=ceil($this->id/pow($this->max_file_count,$i))%$this->max_file_count;
            $dir_file_arr[]=$dir>0?$dir:$this->max_file_count;
            
            $dir_file_str=implode("/", $dir_file_arr);
            if(!is_dir($this->upload_dir.$dir_file_str)) {
                mkdir($this->upload_dir.$dir_file_str, 0777);
                chmod($this->upload_dir.$dir_file_str, 0777);
            }
        }
        file_put_contents($this->upload_dir.$dir_file_str.'/'.$this->id.$fl, $data);
        return $this->upload_dir.$dir_file_str.'/'.$this->id.$fl;
    }
    
    public function set_upload($id,$fl) {
        $this->set_id($id);
        for($i=$this->branches;$i>=1;$i--) {
            $dir=ceil($this->id/pow($this->max_file_count,$i))%$this->max_file_count;
            $dir_file_arr[]=$dir>0?$dir:$this->max_file_count;
            
            $dir_file_str=implode("/", $dir_file_arr);
            if(!is_dir($this->upload_dir.$dir_file_str)) {
                mkdir($this->upload_dir.$dir_file_str, 0777);
                chmod($this->upload_dir.$dir_file_str, 0777);
            }
        }
        return $this->upload_dir.$dir_file_str.'/'.$this->id.$fl;
    }
    
    public function get_upload_dir($id) {
        $this->set_id($id);
        for($i=$this->branches;$i>=1;$i--) {
            $dir=ceil($this->id/pow($this->max_file_count,$i))%$this->max_file_count;
            $dir_file_arr[]=$dir>0?$dir:$this->max_file_count;
        }
            $dir_file_str=implode("/", $dir_file_arr);
        return $this->upload_dir.$dir_file_str.'/'.$this->id;
    }
    
    public function set_upload_dir($id) {
        $this->set_id($id);
        for($i=$this->branches;$i>=1;$i--) {
            $dir=ceil($this->id/pow($this->max_file_count,$i))%$this->max_file_count;
            $dir_file_arr[]=$dir>0?$dir:$this->max_file_count;
            
            $dir_file_str=implode("/", $dir_file_arr);
            if(!is_dir($this->upload_dir.$dir_file_str)) {
                mkdir($this->upload_dir.$dir_file_str, 0777);
                chmod($this->upload_dir.$dir_file_str, 0777);
            }
        }
            if(!is_dir($this->upload_dir.$dir_file_str.'/'.$this->id)) {
                mkdir($this->upload_dir.$dir_file_str.'/'.$this->id, 0777);
                chmod($this->upload_dir.$dir_file_str.'/'.$this->id, 0777);
            }
        return $this->upload_dir.$dir_file_str.'/'.$this->id;
    }

}


GYndt.png
Ответ написан
rdev
@rdev
если картинок очень много то лучше куча папок с несколькими картинками.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы