MySQL中的二进制数据


186

如何在MySQL中存储二进制数据?


1

2
@Nevir:您特别想获得什么信息?您觉得@phpguy@Mat 答案缺少什么?
eggyal

抱歉,我不是要对此进行赏金(使用SO遇到UI错误),但无法删除赏金
Nevir

您应该可以删除赏金
Akshay Giri FR

Answers:


138

phpguy的答案是正确的,但我认为那里的其他细节存在很多混乱。

基本答案是在BLOB数据类型/属性域中。BLOB是Binary Large Object的缩写,该列数据类型特定于处理二进制数据。

请参见MySQL的相关手册页


57

对于这样的表:

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)
);

这是一个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
这段代码看起来像PHP3(或4),已启用register_globals。您不想运行此代码,它也不适用于最新的PHP安装(版本5)。
直到

26
-1为addslashes(),其中需要mysql_real_escape_string()。我们可以停止提供带有SQL注入漏洞的代码吗?(不,addslashes()不够好。)
混乱

40

我强烈建议不要在关系数据库存储二进制数据。关系数据库旨在处理固定大小的数据。那就是他们的性能优势所在:还记得乔尔(Joel)关于数据库为何如此之快的旧文章吗?因为从一条记录移动到另一条记录仅需要1个指针增量。如果添加大小不确定且大小各不相同的BLOB数据,则会提高性能。

而是将文件存储在文件系统中,并将文件名存储在数据库中。


11
我没有拒绝投票,但这可能是由于他暗示您永远不要这样做,而不是在大多数情况下都说这是个坏主意。我总体上同意他的观点,但并非100%的情况。除了性能之外,还有其他注意事项。例如,我现在正在做一些根本不重要的事情。其他因素(例如集中化,简单性和备份)意味着在这种情况下,将数据库存储是有意义的。另一个常见原因是复制。
LaVache

4
另一方面,将数据存储在db中是与操作系统无关的,这对于奇怪的文件名可能是很好的选择。db可以存储具有相同文件名的多个文件,而操作系统不能。它没有读取/写入/删除问题。它不需要额外的备份系统。而且,它不是公开的。因此有时开发速度很快。顺便说一句。没有人会强迫您将所有内容都存储在同一个数据库中,最后所有内容最终都存储在磁盘上。
Joeri 2013年

7
@AlexWeinstein,您正在将二进制数据与固定宽度的数据混淆。二进制数据也可以是固定宽度。固定宽度数据并不适合所有情况。读最后一段:事实上,在很多情况下,你将受益于可变宽度数据dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Pacerier

4
对此,@ Pacerier表示同意,BINARY(16)固定存储。至于BLOB:BLOB具有固定宽度的指针,指向存储在表外部的数据。这与以内联方式存储它的varchar或varbinary不同,搜索blob需要一些额外的步骤,但是将其放在WHERE子句中就可以了。
Garr Godfrey 2015年

4
我还认为在文件系统中存储文件非常损坏且不可移植。如果文件被删除怎么办?
Garr Godfrey 2015年


17

这取决于您要存储的数据。上面的示例使用了LONGBLOB数据类型,但是您应该知道还有其他二进制数据格式:

TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB
VARBINARY
BINARY

每个都有其用例。如果它是已知的(短)长度(例如打包的数据),则经常会BINARYVARBINARY将起作用。它们具有能够对它们进行索引的额外好处。


14

虽然没有必要,但是您可以尝试base64对数据进行编码和解码。这意味着数据库将仅具有ascii字符。这将花费更多的时间和空间,但是与二进制数据有关的任何问题都将被消除。


11

如果存在- 不推荐 -BLOB字段,则可以通过以下方式保存数据:

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

想法取材于此



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.