,我们只存储int和varchar类型的数据,一是因为现代关系型数据库对这些内容有很多优化,二是大多数索引不能应用于具有内容太多,比如文本类型的字段,不适合创建索引。因此,我们在使用数据库的时候,很少会在数据库中存储大的内容字段。不过MySQL其实是为我们准备了这种类型的存储,只是我们平时用的不多而已。今天我们将学习如何使用PDO操作MySQL中的大数据对象。什么是大数据对象“大”通常意味着“大约4kb或更多”,尽管有些数据库在数据达到“大”之前可以轻松处理高达32kb的数据。大对象本质上可能是文本的或二进制的,我们在PDOStatement::bindParam()或PDOStatement::bindColumn()调用中使用PDO::PARAM_LOB类型代码来使PDO使用大数据类型。PDO::PARAM_LOB告诉PDO将数据映射为流,以便可以使用PHPStreamsAPI对其进行操作。对于MySQL,设置字段类型为blob就是大对象格式的字段。在bindParam()或bindColumn()中,如果指定字段的参数是PDO::PARAM_LOB类型,可以直接以句柄的形式获取这个对象的内容,像fopen()一样继续对其进行操作.CREATETABLE`zy_blob`(`id`int(11)NOTNULLAUTO_INCREMENT,`attach`longblob,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_bin;这是我们测试用的数据表,将attach字段设置为longblob类型,这是一个比较大的blob类型,这样我们可以存储更多的信息。毕竟现在的图片或者文件都是随便从几米或者几十米入手的。我们直接使用最大的blob类型进行简单测试。tinyblob的大小为255字节,blob类型的大小为65k,mediumblob为16M,longblob为4G。直接操作大数据对象怎么样?我们先简单的直接操作大数据对象,看看结果如何。$stmt=$pdo->prepare("insertintozy_blob(attach)values(?)");$fp=fopen('4960364865db53dcb33bcf.rar','rb');$stmt->execute([$fp]);$stmt=$pdo->query("selectattachfromzy_blobwhereid=1");$file=$stmt->fetch(PDO::FETCH_ASSOC);print_r($文件);//Array//(//[attach]=>Resourceid#6//)在这段代码中,我们不绑定字段,然后直接将fopen()打开的文件存储到blob字段中。可以看出,在数据库中,blob相关的字段只存储类似Resourceid#6这样的字符串。也就是说,不做任何处理,$fphandle被转成string类型,转成handle类型的结果是只会输出一个资源ID,blob只是字符类型的字段字符串也被记录下来。正确姿势接下来我们来看看正确的姿势,即通过bindParam()插入数据,通过bindColumn()读取数据。$stmt=$pdo->prepare("insertintozy_blob(attach)values(?)");$fp=fopen('4960364865db53dcb33bcf.rar','rb');$stmt->bindParam(1,$fp,PDO::PARAM_LOB);//绑定参数类型为PDO::PARAM_LOB$stmt->execute();$stmt=$pdo->prepare("selectattachfromzy_blobwhereid=2");////$file=$stmt->fetch(PDO::FETCH_ASSOC);////print_r($file);//空$stmt->execute();$stmt->bindColumn(1,$file,PDO::PARAM_LOB);//将列绑定到PHP变量$stmt->fetch(PDO::FETCH_BOUND);//指定fetch方法,返回TRUE并将结果集中的列值赋值给通过PDOStatement::bindParam()或PDOStatement::bindColumn()方法绑定的PHP变量print_r($file);//二进制乱码内容$fp=fopen('a.rar','wb');fwrite($fp,$file);首先,我们通过bindParam()绑定数据并指定PDO::PARAM_LOB类型后,我们通常会将文件句柄的二进制内容插入到数据库中。接下来,我们使用bindColumn()并指定PDO::PARAM_LOB类型来获取查询的数据。直接打印查询到的字段信息,可以看到是二进制类型的内容。最后,我们将这个二进制内容保存到另一个名称的文件中。可以替换上面文件的内容,然后执行代码看看最终生成的文件是否和原来的文件一样。我这里使用的是压缩包文件,最终生成的a.rar文件与原文件大小和解压后的内容完全一致。大数据对象操作总结到底是什么?其实就是我们平时要保存的一个大文件。在我们将这些文件作为二进制流读入程序后,我们将它们存储在数据库的字段中。想想我们平时在开发中用的最多的图片存储,我们可以用这个来做。但是,关键点可以画在这里。建议将文件直接保存在文件目录下,只保存它们在数据库中的路径。数据库资源是宝贵的,表越大越不利于优化,而且数据库本身有缓存机制,浪费资源去保存这么大的文件其实得不偿失。当然,如果有一些特殊的需求,比如一些私有文件不想直接保存在硬盘文件目录下,或者作为临时的跨服务器存储方案,都是可以的。在现代发展中,相信贵公司不会吝啬购买一个云存储(七牛、易云、阿里云OSS)。它们不仅可以作为存储和网盘,还有更多的功能,比如图片裁剪、水印、免费CDN、带宽、流量等。总之,现代存储尽量用云,即使是个人开发,很多厂商也会在小流量、小数据量的情况下提供免费使用,比我们自己的方便多了。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/PDO%E6%93%8D%E4%BD%9C%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%AF%B9%E8%B1%A1.php参考文档:https://www.php.net/manual/zh/pdo.lobs.php所有媒体平台均可搜索【硬核项目经理】
