Datos binarios en MySQL [cerrado]


186

¿Cómo almaceno datos binarios en MySQL ?



2
@Nevir: ¿Qué información buscas específicamente? ¿Qué sientes que falta en las respuestas de @ phpguy's y @ Mat ?
eggyal

Lo siento, no quise recompensar esto (encontré un error de UI con SO), pero no puedo eliminar la recompensa
Nevir

deberías poder eliminar una recompensa
Akshay Giri FR

Respuestas:


138

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

La respuesta básica está en un BLOBdominio de tipo de datos / atributo. BLOB es la abreviatura de Binary Large Object y ese tipo de datos de columna es específico para manejar datos binarios.

Consulte la página del manual correspondiente para MySQL .


57

Para una mesa como esta:

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í hay un ejemplo de PHP:

<?php
    // store.php3 - by Florian Dittmer <dittmer@gmx.net>
    // 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>

9
Este código se parece a PHP3 (o tal vez 4), que register_globals habilitó. No desea ejecutar este código, y tampoco funcionará en una instalación de PHP semi actualizada (que es la versión 5).
Hasta el

26
-1 para addlashes () donde se necesita mysql_real_escape_string (). ¿Podemos dejar de dar código a las personas con vulnerabilidades de inyección SQL? (No, addslashes () no es lo suficientemente bueno.)
caos

40

Recomiendo no almacenar 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á su fortaleza de rendimiento: recuerde el antiguo artículo de Joel sobre por qué las bases de datos son tan rápidas. porque se necesita exactamente un incremento de 1 puntero para moverse de un registro a otro registro. Si agrega datos BLOB de tamaño indefinido y muy variable, arruinará el rendimiento.

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


11
No voté en contra, pero podría deberse a que 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 además del rendimiento. Por ejemplo, ahora estoy trabajando en algo donde el rendimiento no importa en absoluto. 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.
LaVache

44
Por otro lado, el almacenamiento de datos en db es independiente del sistema operativo, lo que puede ser bueno para nombres de archivo extraños. db puede almacenar múltiples archivos con el mismo nombre de archivo, el sistema operativo no. No tiene problemas de lectura / escritura / eliminación. No necesita un sistema de respaldo adicional. Y no es público. Entonces, a veces es rápido en el desarrollo. Por cierto. nadie te obliga a almacenar todo en la misma base de datos, al final todo termina en un disco.
Joeri

77
@AlexWeinstein, estás confundiendo datos binarios con datos de ancho fijo. Los datos binarios también pueden tener un ancho fijo. Y los datos de ancho fijo no son buenos para todas las situaciones. De hecho, en muchas situaciones que se beneficiaría de los datos de anchura variable: leer el último párrafo de dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Pacerier

44
De acuerdo con @Pacerier en esto, BINARY (16) se almacena fijo. En cuanto a BLOB: Un BLOB tiene un puntero de ancho fijo a los datos almacenados fuera de la tabla. Eso es diferente a varchar o varbinary que lo almacenan en línea. Buscar un blob requiere algunos pasos adicionales, pero déjelo fuera de su cláusula WHERE y está bien.
Garr Godfrey

44
También creo que almacenar archivos en el sistema de archivos está muy roto y no es portátil. ¿Qué pasa si el archivo se elimina?
Garr Godfrey


17

Depende de los datos que desea almacenar. El ejemplo anterior utiliza el LONGBLOBtipo de datos, pero 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 es una longitud conocida (corta) (p. Ej., Datos empaquetados), muchas veces BINARYo VARBINARYfuncionará. Tienen el beneficio adicional de poder indexarlos.


14

Si bien no debería ser necesario, podría intentar base64codificar datos y decodificarlos. 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.


11

Si existe el campo - no recomendado - BLOB, puede guardar los datos de esta manera:

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

Idea tomada de aquí .


10

También surge la pregunta de cómo llevar los datos al BLOB. Puede poner los datos en una instrucción INSERT, como muestra el ejemplo de PHP (aunque debería usar mysql_real_escape_string en lugar de addlashes). Si el archivo existe en el servidor de la base de datos, también puede usar LOAD_FILE de MySQL


Ese enlace dice que MySQL_real_escape_string está en desuso.
Poul Bak el

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.