MySQL存储二进制数据

本文详细介绍了如何使用MySQL存储和读取二进制数据,包括关键步骤、具体代码示例及注意事项。代码示例涵盖了C语言实现,适用于PHP和Perl环境。

晚上小研究了下MySQL存储于读取二进制数据的功能。关键步骤为以下三点:

  1. 最重要的一点:存储二进制数据的表的类型需要是blob类型(按长度不同分为tiny, media, long) 
  2. 插入二进制数据时需要利用mysql_real_escape_string函数对数据进行转换
  3. 从数据库中读取二进制数据时需要利用mysql_fetch_length函数字段长度,该函数需要在mysql_fetch_row调用后才可以正常获取结果

给出一个用C写的一个存储与读取字段的小例子,写的比较粗犷,见谅哈~

先来一个插入:

int
db_insert_object(void *object, unsigned int objsize)
{
    int ret;
    char *escape_object = NULL;
    char sql[1024];
    unsigned int escape_size = 2 * objsize + 2;
    int sql_len;
    MYSQL *mysql= NULL;

    /* connnect db */
    mysql = mysql_init(NULL);
    if( !mysql_real_connect(mysql, SERVER, USER, PASSWD, DATABASE, 0, NULL, 0) ){
        goto error1;
    }

    /* convert binary string */
    escape_object = (char *)malloc(escape_size);
    if( escape_object == NULL ){
        goto error1;
    }
    escape_size = mysql_real_escape_string(mysql, escape_object, (char *)object, objsize);

    sql_len = sprintf(sql, "insert into task(object) values('%s')", escape_object);
    ret = mysql_real_query(mysql, sql, sql_len);
    if( ret ){
        goto error1;
    }

    free(escape_object);
    mysql_close(mysql);
    return 0;

error1:
    printf("error: %s\n", mysql_error(mysql));
    if( mysql ) mysql_close(mysql);
    if( escape_object ) free(escape_object);
    return -1;
}

然后是读取:

void *
db_fetch_object()
{
    MYSQL *mysql= NULL;
    MYSQL_RES *res = NULL;
    MYSQL_ROW row;
    unsigned long *row_len;
    char *object = NULL;
    const char *sql = "select object from task limit 1";
    unsigned long objsize;
    int ret;

    /* connnect db */
    mysql = mysql_init(NULL);
    if( !mysql_real_connect(mysql, SERVER, USER, PASSWD, DATABASE, 0, NULL, 0) ){
        goto error2;
    }

    /* get object */
    ret = mysql_real_query(mysql, sql, strlen(sql));
    if( ret ){
        goto error2;
    }

    res = mysql_store_result(mysql);
    if( res == NULL ){
        goto error2;
    }

    /* important */
    row = mysql_fetch_row(res);
    row_len = mysql_fetch_lengths(res);  /* get the object's length */
    if( row_len == NULL ){
        goto error2;
    }
    objsize = row_len[0];
    object  = (char*)malloc(objsize);
    if( object == NULL ){
        goto error2;
    }

    memcpy(object, row[0], objsize);

    mysql_close(mysql);
    mysql_free_result(res);
    return (void*)object;

error2:
    printf("error: %s\n", mysql_error(mysql));
    if( res ) mysql_free_result(res);
    if( mysql ) mysql_close(mysql);
    if( object ) free(object);
    return NULL;
}

PHP以及perl中的操作也是大同小异~

OVER~

转载于:https://www.cnblogs.com/aLittleBitCool/archive/2012/08/14/2638831.html

<think>好的,我现在需要帮助用户了解如何在MySQL存储二进制数据。首先,我得回忆一下MySQL支持哪些数据类型适合存储二进制数据。记得有BLOB类型,包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB,分别对应不同的存储容量。用户可能想知道这些类型的具体区别和使用场景。 然后,用户可能想知道实际操作的步骤,比如如何创建表结构来存储二进制数据。需要给出一个示例的建表语句,说明各个字段的作用,比如描述、文件名、文件大小、文件类型等,以及BLOB类型的字段用于存储二进制数据本身。 接下来,用户可能关心如何通过编程语言(比如PHP)将二进制数据插入数据库。需要提到使用预处理语句来防止SQL注入,并且处理文件上传时的读取操作,比如用fread函数读取文件内容。同时,要强调使用参数绑定,比如在PHP中使用PDO或mysqli的bind_param方法。 另外,注意事项也很重要。比如BLOB类型的大小限制,不同版本MySQL的配置可能会影响允许的最大数据包大小(max_allowed_packet),需要提醒用户根据实际需求调整。还要提到性能问题,存储大文件可能会影响数据库性能,建议大文件在文件系统中,数据库中只路径。备份和恢复方面,二进制数据会增加备份的大小和时间,这也是需要考虑的因素。 可能还需要补充一些最佳实践,比如结合文件系统存储,或者使用专门的存储解决方案。此外,用户可能想知道如何检索和显示这些二进制数据,比如从数据库读取后输出为图片或文件,但用户当前的问题可能主要关注存储方法,这部分可以简要提及。 最后,根据用户提供的引用内容,他们之前可能接触过一些不规范的示例代码,比如直接拼接SQL语句,这可能在安全风险。所以在回答中需要强调使用预处理语句和参数化查询的重要性,避免SQL注入攻击。 总结一下,回答的结构应该是先介绍数据类型,然后创建表的示例,接着插入数据的步骤和代码示例,注意事项,以及相关的最佳实践。同时,生成相关问题帮助用户进一步学习,比如性能优化、结合应用开发的具体实现,以及不同数据类型的比较。</think>在MySQL存储二进制数据主要通过`BLOB`类型实现,具体方法如下: ### 一、MySQL支持的二进制数据类型 1. **`BLOB`系列**: - `TINYBLOB`:最大存储$255$字节 - `BLOB`:最大存储$64$KB - `MEDIUMBLOB`:最大存储$16$MB - `LONGBLOB`:最大存储$4$GB[^1] 2. **二进制字符串类型**: - `BINARY(n)`:固定长度二进制字符串 - `VARBINARY(n)`:可变长度二进制字符串 ### 二、实际操作步骤 #### 1. 创建表结构示例 ```sql CREATE TABLE binary_data ( id INT AUTO_INCREMENT PRIMARY KEY, description VARCHAR(255), bin_data LONGBLOB, filename VARCHAR(255), filesize INT, filetype VARCHAR(50) ); ``` #### 2. 插入二进制数据(PHP示例) ```php $file = $_FILES['uploaded_file']; $data = file_get_contents($file['tmp_name']); $stmt = $pdo->prepare("INSERT INTO binary_data (description, bin_data, filename, filesize, filetype) VALUES (?, ?, ?, ?, ?)"); $stmt->bindParam(1, $description); $stmt->bindParam(2, $data, PDO::PARAM_LOB); $stmt->bindParam(3, $file['name']); $stmt->bindParam(4, $file['size']); $stmt->bindParam(5, $file['type']); $stmt->execute(); ``` ### 三、注意事项 1. **性能优化**: - 超过$1$MB的文件建议存储在文件系统,数据库只保路径 - 调整`max_allowed_packet`参数(默认$64$MB) 2. **安全规范**: - 必须使用预处理语句防止SQL注入[^2] - 限制上传文件类型和大小 3. **检索数据示例**: ```php $stmt = $pdo->query("SELECT bin_data,filetype FROM binary_data WHERE id=1"); header("Content-Type: " . $row['filetype']); echo $row['bin_data']; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值