ホームページ  >  記事  >  データベース  >  PDO がビッグ データ オブジェクトを操作する方法

PDO がビッグ データ オブジェクトを操作する方法

醉折花枝作酒筹
醉折花枝作酒筹転載
2021-06-10 17:06:072923ブラウズ

この記事では、PDO でビッグ データ オブジェクトを操作する方法を詳しく紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

PDO がビッグ データ オブジェクトを操作する方法

通常、データベースには、int 型と varchar 型のデータのみが保存されます。第一に、最新のリレーショナル データベースではこれらの内容に対して多くの最適化が行われており、第二に、ほとんどのインデックスはこれらのデータを保存できません。コンテンツが多すぎるフィールドには適用できません。たとえば、テキスト タイプのフィールドはインデックスの作成には適していません。したがって、データベースを使用する場合、大きなコンテンツ フィールドをデータベースに保存することはほとんどありません。ただし、MySQL は実際にはこのタイプのストレージを用意していますが、通常はあまり使用しません。今日は、PDO を使用して MySQL でビッグ データ オブジェクトを操作する方法を学びます。

ビッグ データ オブジェクトとは

「大規模」とは通常「約 4kb 以上」を意味しますが、データベースによっては「大規模な」ハンドルに達する前にデータを簡単に保存できるものもあります。データは32kbまで。大きなオブジェクトは本質的にテキストまたはバイナリである可能性があり、PDOStatement::bindParam() または PDOStatement::bindColumn() 呼び出しで PDO::PARAM_LOB 型コードを使用することで、PDO に大きなデータ型を使用させることができます。 PDO::PARAM_LOB は、PHP Streams API を使用してデータを操作できるように、データをストリームとしてマップするように PDO に指示します。

MySQL の場合、フィールド タイプを blob に設定すると、ラージ オブジェクト形式のフィールドになります。 bindParam() または bindingColumn() を使用する場合、指定されたフィールドのパラメーターが PDO::PARAM_LOB 型の場合、このオブジェクトの内容をハンドルの形式で直接取得し、fopen( と同様に操作を続けることができます) )。

CREATE TABLE `zy_blob` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `attach` longblob,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

これはテスト用のデータ テーブルです。より多くの情報を保存できるように、添付フィールドはより大きな BLOB タイプである longblob タイプに設定されています。結局のところ、今日の写真やファイルは簡単に数 MB または数十 MB から始まる可能性があるため、簡単なテストには最大の BLOB タイプを直接使用します。 tinyblob のサイズは 255 バイト、blob タイプのサイズは 65k、mediumblob は 16M、longblob は 4G です。

ビッグデータオブジェクトを直接操作するとどうなるでしょうか?

まず、ビッグ データ オブジェクトを直接操作して、結果を見てみましょう。

$stmt = $pdo->prepare("insert into zy_blob (attach) values (?)");
$fp = fopen('4960364865db53dcb33bcf.rar', 'rb');
$stmt->execute([$fp]);

$stmt = $pdo->query("select attach from zy_blob where id=1");
$file = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($file); 
// Array
// (
//     [attach] => Resource id #6
// )

このコードでは、フィールドをバインドせず、fopen() によって開かれたファイルを blob フィールドに直接保存します。データベースでは、BLOB 関連フィールドにはリソース ID #6 などの文字列のみが格納されていることがわかります。つまり、何も処理せずに、$fp ハンドルは文字列型に強制され、ハンドル型が強制された結果、リソース ID のみが出力され、BLOB は文字型と同じになるだけになります。この文字列は記録されたばかりです。

正しい姿勢

次に、正しい姿勢を見てみましょう。これは、bindParam() を介してデータを挿入し、bindColumn() を介してデータを読み取ることです。

$stmt = $pdo->prepare("insert into zy_blob (attach) values (?)");

$fp = fopen('4960364865db53dcb33bcf.rar', 'rb');

$stmt->bindParam(1, $fp, PDO::PARAM_LOB); // 绑定参数类型为 PDO::PARAM_LOB
$stmt->execute();

$stmt = $pdo->prepare("select attach from zy_blob where id=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); // 指定获取方式,返回 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 ファイルは、元のファイルおよび解凍されたコンテンツとまったく同じサイズになります。

概要

ビッグ データ オブジェクトは正確に何を操作するのでしょうか?実際、私たちが通常保存するのは大きなファイルです。これらのファイルをバイナリ ストリームとしてプログラムに読み込んだ後、データベースのフィールドに保存します。日々の開発で使用するほとんどの写真を保存することを考えると、これを使用できます。ただし、ここで重要な点がわかります。ファイルはファイル ディレクトリに直接保存し、データベースにはパスのみを保存することをお勧めします。データベース リソースは貴重です。テーブルが大きくなるほど、最適化は難しくなります。さらに、データベース自体にはキャッシュ メカニズムが備わっています。このような大きなファイルを保存するためにリソースを無駄にするのは価値がありません。もちろん、いくつかの特別なニーズがある場合、たとえば、一部のプライベート ファイルをハードディスク ファイル ディレクトリに直接保存したくない場合や、一時的なクロスサーバー ストレージ ソリューションとして使用することもできます。

在现代开发中,相信你的公司也不会吝啬到不去买一个云存储(七牛、upyun、阿里云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

相关推荐:《mysql教程

以上がPDO がビッグ データ オブジェクトを操作する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。