Dados binários no MySQL [fechado]

186

Como guardo dados binários no MySQL ?

Geoff Dalgas
fonte
2
@Nevir: Quais informações você procura especificamente? O que você acha que falta nas respostas de @ phpguy's e @ Mat ?
eggyal
Desculpe, eu não tive a intenção de recompensar isso (ocorreu um bug na interface do usuário com o SO), mas não consigo removê
lo
você deve ser capaz de remover uma recompensa
Akshay Giri FR

Respostas:

138

A resposta do phpguy está correta, mas acho que há muita confusão nos detalhes adicionais.

A resposta básica está em um BLOBdomínio de tipo / atributo de dados. BLOB é a abreviação de Objeto Grande Binário e esse tipo de dados da coluna é específico para manipular dados binários.

Veja a página de manual relevante para MySQL .

Esteira
fonte
57

Para uma tabela 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)
);

Aqui está um exemplo do 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>
mauris
fonte
9
Esse código se parece com o PHP3 (ou talvez 4), habilitado pelo register_globals. Você não deseja executar este código, e ele também não funcionará em uma instalação PHP semi-atualizada (que é a versão 5).
Até
26
-1 para addlashes () onde mysql_real_escape_string () é necessário. Podemos parar de fornecer código às pessoas com vulnerabilidades de injeção de SQL? (Não, o addslashes () NÃO é bom o suficiente).
caos
40

Eu recomendo fortemente contra o armazenamento de dados binários em um banco de dados relacional. Os bancos de dados relacionais são projetados para trabalhar com dados de tamanho fixo; é aí que está a força do desempenho: lembra-se do antigo artigo de Joel sobre por que os bancos de dados são tão rápidos? porque é preciso exatamente 1 incremento de ponteiro para passar de um registro para outro. Se você adicionar dados BLOB de tamanho indefinido e muito variável, você estragará o desempenho.

Em vez disso, armazene arquivos no sistema de arquivos e armazene nomes de arquivos no seu banco de dados.

Alex Weinstein
fonte
11
Eu não diminuí o voto, mas pode ser devido a ele implicar que você NUNCA deve fazê-lo, em vez de dizer que é uma má ideia na maioria das vezes. Eu concordo com ele em geral, mas não em 100% dos casos. Pode haver outras considerações além do desempenho. Por exemplo, estou trabalhando em algo agora em que o desempenho não importa. Outros fatores como centralização, simplicidade e backups significam que, nesse caso, o armazenamento no banco de dados faz sentido. Outro motivo comum é a replicação.
21413 LaVache
4
Por outro lado, o armazenamento de dados no db é independente do SO, o que pode ser bom para nomes de arquivos estranhos. o db pode armazenar vários arquivos com o mesmo nome de arquivo, o sistema operacional não. Não possui problemas de leitura / gravação / exclusão. Não precisa de um sistema de backup adicional. E não é público. Às vezes, é rápido no desenvolvimento. Btw. ninguém está forçando você a armazenar tudo no mesmo banco de dados; no final, tudo acaba em um disco.
Joeri
7
@AlexWeinstein, você está confundindo dados binários com dados de largura fixa. Os dados binários também podem ter largura fixa. E os dados de largura fixa não são bons para todas as situações. De fato, em muitas situações você se beneficiaria de dados de largura variável: último parágrafo ler de dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Pacerier
4
De acordo com o @Pacerier, BINARY (16) é armazenado fixo. Quanto ao BLOB: um BLOB possui um ponteiro de largura fixa para dados armazenados fora da tabela. Isso é diferente do varchar ou do varbinary que o armazena em linha. A pesquisa de um blob requer algumas etapas extras, mas deixe-o fora da cláusula WHERE e tudo bem.
Garr Godfrey
4
Eu também acho que armazenar arquivos no sistema de arquivos é muito quebrado e não é portátil. e se o arquivo for excluído?
Garr Godfrey
22

Embora você não tenha dito o que está armazenando e possa ter um ótimo motivo para fazê-lo, geralmente a resposta é 'como uma referência ao sistema de arquivos' e os dados reais estão no sistema de arquivos em algum lugar.

http://www.onlamp.com/pub/a/onlamp/2002/07/11/MySQLtips.html

Issac Kelly
fonte
17

Depende dos dados que você deseja armazenar. O exemplo acima usa o LONGBLOBtipo de dados, mas você deve estar ciente de que existem outros formatos de dados binários:

TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB
VARBINARY
BINARY

Cada um tem seus casos de uso. Se for um comprimento conhecido (curto) (por exemplo, dados compactados), muitas vezes BINARYou VARBINARYfuncionará. Eles têm o benefício adicional de poder indexar neles.

d0nut
fonte
14

Embora não seja necessário, você pode tentar base64codificar e descodificar dados. Isso significa que o banco de dados terá apenas caracteres ascii. Isso levará um pouco mais de espaço e tempo, mas qualquer problema relacionado aos dados binários será eliminado.

user10117
fonte
11

Se o campo - não recomendado - BLOB existir, você poderá salvar os dados desta maneira:

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

Idéia tirada daqui .

Comunidade
fonte
10

Surge também a questão de como colocar os dados no BLOB. Você pode colocar os dados em uma instrução INSERT, como mostra o exemplo do PHP (embora você deva usar mysql_real_escape_string em vez de addlashes). Se o arquivo existir no servidor de banco de dados, você também poderá usar o LOAD_FILE do MySQL.

Scott Noyes
fonte
Esse link diz que o MySQL_real_escape_string está obsoleto.
Poul Bak