PDO操作大資料物件
一般在資料庫中,我們儲存的都只是 int 、 varchar 型別的資料,一是因為現代的關係型資料庫對於這些內容會有很多的最佳化,二是大部分的索引也無法施加在內容過多的欄位上,比如說 text 型別的欄位就很不適合建立索引。所以,我們在使用資料庫時,很少會向資料庫中儲存很大的內容欄位。但是,MySQL 其實也為我們準備了這種型別的儲存,只是我們平常用得不多而已。今天我們就來學習瞭解一下使用 PDO 如何操作 MySQL 中的大資料物件。
什麼是大資料物件
“大”通常意味著“大約 4kb 或以上”,儘管某些資料庫在資料達到“大”之前可以輕鬆地處理多達 32kb 的資料。大物件本質上可能是文字或二進位制形式的,我們在 PDOStatement::bindParam() 或 PDOStatement::bindColumn() 呼叫中使用 PDO::PARAM_LOB 型別碼可以讓 PDO 使用大資料型別。PDO::PARAM_LOB 告訴 PDO 作為流來對映資料,以便能使用 PHP Streams API 來操作。
對於 MySQL 來說,將欄位型別設定為 blob 即是大物件格式的欄位。而在 bindParam() 或 bindColumn() 時,指定欄位的引數為 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;
這是我們測試用的一個資料表,將 attach 欄位設定為了 longblob 型別,也就是比較大的 blob 型別,這樣我們就可以儲存更多地資訊。畢竟現在的圖片或檔案隨隨便便就是輕鬆地幾m或幾十m起步的,我們直接使用最大的 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 相關的欄位只是儲存了 Resource 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 、頻寬 、 流量之類的,總之,現代的儲存大家還是儘量上雲吧,即使是個人開發,也有不少廠商會提供小流量小資料量情況下的免費使用,這個都比我們自己來要方便很多。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4687/viewspace-2797513/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用Chatgpt編寫的PHP資料庫pdo操作類(增刪改查)ChatGPTPHP資料庫
- PHP 資料庫擴充之 PDOPHP資料庫
- 自寫的使用PDO對mysql資料庫的增刪改查操作類MySql資料庫
- 靜態PDO基礎操作封裝封裝
- 大資料學習:物件大資料物件
- 教你如何用php pdo連線資料庫PHP資料庫
- pdo_mysql 資料庫亂碼問題MySql資料庫
- PHP 遠端使用 PDO 連線 access 資料庫PHP資料庫
- Oracle OCP(11):操作大資料集Oracle大資料
- Python操作三大主流資料庫Python資料庫
- CANopen學習筆記(二)通訊物件PDO和SDO等筆記物件
- 物件代理資料庫:大資料時代下的應需之作物件資料庫大資料
- 大資料系列2:Hdfs的讀寫操作大資料
- 大資料學習之路——java物件導向(二)大資料Java物件
- JS 中普通物件資料型別的基本結構和操作JS物件資料型別
- PDO_dblib
- 新版本一定要用PDO才能連線資料庫了嗎?資料庫
- PDO 長連線
- 客快物流大資料專案(四十五):Spark操作Kudu DML操作大資料Spark
- 雲端計算大資料學習路線課程大綱資料:hive入門操作大資料Hive
- 通過配置hibernate方言包+GBase8s jdbc實現clob、blob、text、byte大物件資料型別操作JDBC物件資料型別
- UMStor Hadapter:大資料與物件儲存的柳暗花明APT大資料物件
- 資料庫操作資料庫
- 資料夾操作
- 資料庫操作·資料庫
- 新增模型物件操作模型物件
- 客快物流大資料專案(四十六):Spark操作Kudu dataFrame操作kudu大資料Spark
- PHP中的PDO操作學習(二)預處理語句及事務PHP
- Redis-資料結構與物件-物件Redis資料結構物件
- pdo的用處,用法
- PDO 的 exec 和 query
- PHP PDO 簡單教程PHP
- innobackupex備份mysql大資料(全量+增量)操作記錄MySql大資料
- 值得白嫖的資料庫常用操作語句彙總(資料庫、資料表、資料操作)資料庫
- 【SpringMVC】域物件共享資料SpringMVC物件
- Redis資料基本操作Redis
- MySQL 資料表操作MySql
- MySQL 資料庫操作MySql資料庫