2008-08-01 45 views
159

¿Cómo almaceno datos binarios en MySQL?Datos binarios en MySQL

+0

[almacenar-imágenes-en-db-sí-o-nay] (https://stackoverflow.com/questions/3748/) –

+1

@ Nevir: ¿Qué información busca específicamente? ¿Qué cree que le falta a [@ phpguy's] (https://stackoverflow.com/questions/17/binary-data-in-mysql#18) y [@ Mat's] (https://stackoverflow.com/questions/ 17/binary-data-in-mysql # 26) respuestas? – eggyal

+0

Lo siento, no quise recompensar esto (me encontré con un error de UI con SO), pero no puedo eliminar el bounty – Nevir

Respuesta

122

La respuesta por phpguy es correcta, pero creo que hay mucha confusión en los detalles adicionales allí .

La respuesta básica está en un dominio de tipo de datos/atributos BLOB. BLOB es la abreviatura de Objeto grande binario y ese tipo de datos de columna es específico para el manejo de datos binarios.

Ver the relevant manual page for MySQL.

50

Para una tabla como la siguiente:

CREATE TABLE binary_data (
    id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    description CHAR(50), 
    bin_data LONGBLOB, 
    filename CHAR(50), 
    filesize CHAR(50), 
    filetype CHAR(50) 
); 

Aquí está un ejemplo de PHP:

<?php 
    // store.php3 - by Florian Dittmer <[email protected]> 
    // Example php script to demonstrate the storing of binary files into 
    // an sql database. More information can be found at http://www.phpbuilder.com/ 
?> 

<html> 
    <head><title>Store binary data into SQL Database</title></head> 

    <body> 
     <?php 
      // Code that will be executed if the form has been submitted: 

      if ($submit) { 
       // Connect to the database (you may have to adjust 
       // the hostname, username or password). 

       mysql_connect("localhost", "root", "password"); 
       mysql_select_db("binary_data"); 

       $data = mysql_real_escape_string(fread(fopen($form_data, "r"), filesize($form_data))); 

       $result = mysql_query("INSERT INTO binary_data (description, bin_data, filename, filesize, filetype) ". 
            "VALUES ('$form_description', '$data', '$form_data_name', '$form_data_size', '$form_data_type')"); 

       $id= mysql_insert_id(); 
       print "<p>This file has the following Database ID: <b>$id</b>"; 

       mysql_close(); 
      } else { 

       // else show the form to submit new data: 
     ?> 
     <form method="post" action="<?php echo $PHP_SELF; ?>" enctype="multipart/form-data"> 
      File Description:<br> 
      <input type="text" name="form_description" size="40"> 
      <input type="hidden" name="MAX_FILE_SIZE" value="1000000"> 
      <br>File to upload/store in database:<br> 
      <input type="file" name="form_data" size="40"> 
      <p><input type="submit" name="submit" value="submit"> 
     </form> 

     <?php 
      } 
     ?> 
    </body> 
</html> 
+8

Este código se parece a PHP3 (o quizás 4), que register_globals habilitado. No desea ejecutar este código, y tampoco funcionará en una instalación PHP semi actualizada (que es la versión 5). – Till

+21

-1 para addslashes() donde mysql_real_escape_string() es necesario. ¿Podemos por favor dejar de darle código a las personas con vulnerabilidades de inyección SQL? (No, addslashes() NO es suficiente.) – chaos

8

También surge la pregunta de cómo obtener los datos en el BLOB. Puede colocar los datos en una instrucción INSERT, como muestra el ejemplo de PHP (aunque debe usar mysql_real_escape_string en lugar de addslashes). Si el archivo existe en el servidor de la base de datos, también puede utilizar MySQL's LOAD_FILE

12

Si bien no debería ser necesario, puede probar base64 codificando datos y descodificándolos. Eso significa que el DB solo tendrá caracteres ascii. Tomará un poco más de espacio y tiempo, pero se eliminará cualquier problema relacionado con los datos binarios.

7

Implementación de almacenamiento mucho mejor en here disponible. Te encontrarás con problemas con la implementación de Florian.

35

Recomiendo encarecidamente contra almacenando datos binarios en una base de datos relacional. Las bases de datos relacionales están diseñadas para trabajar con datos de tamaño fijo; ahí es donde está la fortaleza de su rendimiento: recuerde Joel's old article ¿por qué las bases de datos son tan rápidas? porque toma exactamente 1 incremento de puntero para pasar de un registro a otro. Si agrega datos BLOB de tamaño indefinido y muy variable, arruinará el rendimiento.

En su lugar, almacene los archivos en el sistema de archivos y almacene los nombres de los archivos en su base de datos.

+10

No he votado negativamente, pero podría deberse a que él insinúa que NUNCA debes hacerlo, en lugar de decir que es una mala idea la mayor parte del tiempo. Estoy de acuerdo con él en general, pero no en el 100% de los casos. Puede haber otras consideraciones aparte del rendimiento. Por ejemplo, estoy trabajando en algo ahora donde el rendimiento no importa para nada. Otros factores como la centralización, la simplicidad y las copias de seguridad significan que en este caso el almacenamiento en la base de datos tiene sentido. Otra razón común es la replicación. – YeB

+1

El campo BLOB tiene un tamaño fijo de 64 kilobytes. No está variando, ¿verdad? –

+0

64 KB no cabe en muchos archivos, por lo que deberá tener más de un bloque de 64 KB para almacenar los datos. –

15

Depende de los datos que desea almacenar. El ejemplo anterior utiliza el tipo de datos LONGBLOB, pero se debe tener en cuenta que existen otros formatos de datos binarios:

TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB
VARBINARY
BINARY

Cada uno tiene sus casos de uso. Si se trata de una longitud conocida (corta) (por ejemplo, datos empaquetados), muchas veces BINARY o VARBINARY funcionarán. Tienen el beneficio adicional de poder tener un índice sobre ellos.

9

Si el - not recommended - existe campo BLOB, puede guardar datos de esta manera:

mysql_query("UPDATE table SET field=X'".bin2hex($bin_data)."' WHERE id=$id"); 

Idea tomada de here.

Cuestiones relacionadas