ФорумПрограммированиеПыхнуть хотите?F.A.Q. → Хранение изображений в базе данных MySQL

Хранение изображений в базе данных MySQL

  • maxfr

    Сообщения: ? Репутация: N Группа: Кто попало

    Spritz 2 апреля 2009 г. 4:17

    Для хранения изображений в базе данных MySQL необходимо определить одно из полей таблицы как производное от типа BLOB. Сокращение BLOB означает большой двоичный объект. Тип хранения данных BLOB обладает несколькими вариантами:

       * TINYBLOB - может хранить до 255 байт
       * BLOB - может хранить до 64 килобайт информации
       * MEDIUMBLOB - до 16 мегабайт
       * LONGBLOB - до 4 гигабайт

    Соответсвенно, для хранения изображений нам надо создать таблицу images с двумя полями:

       * id - уникальный ID изображения
       * content - поле для хранения изображения

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

    <?php
    // Соединяемся с сервером БД
    mysql_connect ( &#39;localhost&#39;, &#39;root&#39;, &#39;&#39; );
    mysql_query( &#39;SET NAMES cp1251&#39; );
    mysql_select_db ( &#39;images&#39; );

    if( $_SERVER[&#39;REQUEST_METHOD&#39;] == &#39;POST&#39; ) {
     // Проверяем пришел ли файл
     if( !empty( $_FILES[&#39;image&#39;][&#39;name&#39;] ) ) {
       // Проверяем, что при загрузке не произошло ошибок
       if ( $_FILES[&#39;image&#39;][&#39;error&#39;] == 0 ) {
         // Если файл загружен успешно, то проверяем - графический ли он
         if( substr($_FILES[&#39;image&#39;][&#39;type&#39;], 0, 5)==&#39;image&#39; ) {
           // Читаем содержимое файла
           $image = file_get_contents( $_FILES[&#39;image&#39;][&#39;tmp_name&#39;] );
           // Экранируем специальные символы в содержимом файла
           $image = mysql_escape_string( $image );
           $title = mysql_escape_string( $_POST[&#39;title&#39;] );
           // Формируем запрос на добавление файла в базу данных
           $query=&quot;INSERT INTO `images` VALUES(NULL, &#39;&quot;.$title.&quot;&#39;, &#39;&quot;.$image.&quot;&#39;)&quot;;
           // После чего остается только выполнить данный запрос к базе данных
           mysql_query( $query );
         }
       }
     }
    }
    ?>
    <html>
    <head>
    <title>Загрузка изображений</title>
    <meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=windows-1251&quot;>
    </head>
    <body>
    <h3>Загруженные изображения</h3>
    <p>
    <?php
    $query = &quot;SELECT id, title FROM images WHERE 1 ORDER BY id&quot;;
    $res = mysql_query( $query );
    while( $img = mysql_fetch_array( $res ) ) {
     echo &#39;<img src=&quot;image.php?id=&#39;.$img[&#39;id&#39;].&#39;&quot; alt=&quot;&#39;.$img[&#39;id&#39;].&#39;&quot; />&#39;;
    }
    ?>
    </p>
    <form enctype=&quot;multipart/form-data&quot; method=&quot;post&quot; action=&quot;<?php echo $_SERVER[&#39;PHP_SELF&#39;] ?>&quot;>
    Наименование: <input type=&quot;text&quot; name=&quot;title&quot; value=&quot;&quot; /><br/>
    Изображение: <input type=&quot;file&quot; name=&quot;image&quot; /><br/>
    <input type=&quot;submit&quot; value=&quot;Загрузить&quot; />
    </form>
    </body>
    </html>


    image.php

    <?php
    // Соединяемся с сервером БД
    mysql_connect ( &#39;localhost&#39;, &#39;root&#39;, &#39;&#39; );
    mysql_query( &#39;SET NAMES cp1251&#39; );
    mysql_select_db ( &#39;images&#39; );

    if ( isset( $_GET[&#39;id&#39;] ) ) {
     // Здесь $id номер изображения
     $id = (int)$_GET[&#39;id&#39;];
     if ( $id > 0 ) {
       $query = &quot;SELECT `content` FROM `images` WHERE `id`=&quot;.$id;
       // Выполняем запрос и получаем файл
       $res = mysql_query($query);
       if ( mysql_num_rows( $res ) == 1 ) {
         $image = mysql_fetch_array($res);
         // Отсылаем браузеру заголовок, сообщающий о том, что сейчас будет передаваться файл изображения
         header(&quot;Content-type: image/*&quot;);
         // И  передаем сам файл
         echo $image[&#39;content&#39;];
       }
     }
    }
    ?>


    Вот и дамп таблицы images.

    CREATE TABLE `images` (
     `id` int(11) NOT NULL auto_increment,
     `title` varchar(255) NOT NULL,
     `content` blob NOT NULL default &#39;&#39;,
     PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=cp1251;
  • md5

    Сообщения: 11951 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 4:20, спустя 2 минуты 39 секунд

    нахуй надо хранить изображения в базе
    ояебу, я опиздошен
    все умрут, а я изумруд
  • maxfr

    Сообщения: ? Репутация: N Группа: Кто попало

    Spritz 2 апреля 2009 г. 4:27, спустя 7 минут 31 секунду


    нахуй надо хранить изображения в базе
    ояебу, я опиздошен

    Статья выложена для общего развития.

    ИМХО: способ правда ебуч***. ПхпМуАдмин грузится очень долго.
  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 4:29, спустя 1 минуту 40 секунд


    нахуй надо хранить изображения в базе
    ояебу, я опиздошен


    Не всегда это так плохо, как кажется.
    adw/0
  • Trej Gun

    Сообщения: 5299 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 4:33, спустя 3 минуты 44 секунды

    у оракла достук к своим данным быстрее чем у файловой системы ос
  • Trej Gun

    Сообщения: 5299 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 4:33, спустя 23 секунды

    это я о том что если хранить картинки в бд оракла то это не так уж плохо
  • AlexB

    Сообщения: 4288 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 4:51, спустя 17 минут 46 секунд


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

    Для мускула я пока с такой необходимость не сталкивался, но теоритически тоже можно найти причину. Например репликация базы на slave сервера.
  • Patrick

    Сообщения: ? Репутация: N Группа: Кто попало

    Spritz 2 апреля 2009 г. 4:56, спустя 5 минут 12 секунд

    CTAPbIu_MABP, сам тестил?
    фак как НЕ надо хранить данные в БД
  • Patrick

    Сообщения: ? Репутация: N Группа: Кто попало

    Spritz 2 апреля 2009 г. 4:58, спустя 2 минуты 4 секунды

    AlexB, а не проще было парсить доки и строить индекс тем же сфинксом
  • AlexB

    Сообщения: 4288 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 5:02, спустя 3 минуты 51 секунду

    А чем их парсить?

    А про sphinx мы тогда не знали (он кстати когда появился? да и там MS был полюбому), это вообще дело давнее и наверно было дофига архитектурных косяков, просто привел как пример осмыслленного выбора хранения файлов в БД.
  • Givi

    Сообщения: ? Репутация: N Группа: Адекваты

    Spritz 2 апреля 2009 г. 5:03, спустя 1 минуту 26 секунд

    AlexB, думаю что и с файловой системой репликацию можно сделать (если я правильно понимаю что такое репликация в твоем примере).
    А в целом ФС удобнее тем, что можно имаги хранить отдельной пачкой, и можно с ними на физическом уровне делать что угодно, не прибегая к нагрузке (выборка из базы) БД. Конечно же, не для всех задач. Просто мой ИМХО - хранение в картинок БД это отстой.

    п.с. О репликации вообще знаю очень мало, так как с этим пока работать не приходилось.
    п.с.2 У нас есть одна база, где храняться данные юзверей + пароли. Так вот пароли храняться в БЛОБе. Типа через ПМА не видно, работать с ними (паролями) неудобно. А в целом они не хешированные, а открытые текстовые файлики. Просто программист когда это писал, был ещё очень зеленым. Да и было это давно, а переделывать никто не хочет.
  • AlexB

    Сообщения: 4288 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 5:06, спустя 3 минуты 4 секунды


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

    Сообщения: ? Репутация: N Группа: Кто попало

    Spritz 2 апреля 2009 г. 5:15, спустя 8 минут 33 секунды

    А чем их парсить?

    либы думаю есть эт не проблема
  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 5:19, спустя 4 минуты 5 секунд

    Patrick, ты работал с MS форматами офисных пакетов? Либы то есть, опять таки использующие OLE/COM и т.д., то же использует и MS SQL.

    Вопрос, зачем писать сторонние решения, если это проще решить средствами самой СУБД? Тем более каждый раз когда что-то меняется в файла - надо заново индексировать… и добавлять в БД… Только гемор добавится…
    adw/0
  • md5

    Сообщения: 11951 Репутация: N Группа: в ухо

    Spritz 2 апреля 2009 г. 5:20, спустя 1 минуту 12 секунд



    нахуй надо хранить изображения в базе
    ояебу, я опиздошен


    Не всегда это так плохо, как кажется.
    да нет ничего универсального, кто ж спорит

    у оракла достук к своим данным быстрее чем у файловой системы ос
    не вижу тут оракла
    все умрут, а я изумруд

Пожалуйста, авторизуйтесь, чтобы написать комментарий!