天天看點

php操作sqlite3

距離上次接觸sqlite3已經快一年了,去年這篇文章講跟着菜鳥教程學python操作sqlite3

現在回頭看看,在php的環境下用sqlite3也是小項目值得選擇的。

老生常談的安裝

install sqlite3 php擴充以及GUI工具

sudo apt-get install sqlite3
sudo apt-get install php7.4-sqlite
sudo apt-get install sqlitebrowser      

具體代碼操作看這裡 https://www.runoob.com/sqlite/sqlite-php.html 人家寫的很詳細了

php官方手冊 看這裡 https://www.php.net/manual/en/book.sqlite3.php

總結出來最重要的也就是這3個方法

query 發送查詢
exec 更新删除增加修改表結構
fetchArray 擷取結果集

動手試了試,感覺效率上和mysql讀差不多,但是寫入可能不太适合并發,畢竟這東西的鎖顆粒度太大了。測試了一下寫入速度

php sqlite3 insert

1. 不關閉 autocommit每條SQL都自動送出的話

  1.1 單條插入 每秒大概 72 條

  1.2 insert values 多值 value 放 1000 個 每秒大概 43489 左右

2. 先關閉 autocommit 最後結束再 autocommit

  2.1 單條插入 每秒大概 158000 條 (100萬條資料在6秒左右插入完成)

  2.2 insert values 多值 value 放 1000 個 每秒大概 264340 左右 (100萬條資料在3.78秒左右插入完成)

問題是 sqlite 是檔案鎖 整個資料庫檔案會被鎖住的 适合單機非并發伺服器

分析得出 可以使用 insert value 多值的方式 配合 begin commit 這種方式手動送出 能讓sqlite3迅速插入上百萬資料

$db->exec('BEGIN');

$ret = $db->exec($sql);

$db->exec('COMMIT');

查詢的話,這裡資料庫放了1000萬條記錄,如果用id查詢那很快的,基本上0.3ms左右,如果是其他字段查詢的話,立刻就上400ms以上了,即使符合條件的記錄隻有一條也是這樣,看了一下因為我使用了這樣的代碼

while($row = $ret->fetchArray(SQLITE3_ASSOC)){
    $data[]=$row;
}      

這樣的循環,在最後一次拿不到值的時候會等待很久,不知道是什麼問題,還沒有深入研究。如下代碼可很容易看出問題

$row = $ret->fetchArray(SQLITE3_ASSOC);//這一行執行很快
$row = $ret->fetchArray(SQLITE3_ASSOC);//這一行執行很慢 因為符合的記錄隻有一條      

感覺是如果用ID查,它能知道有多少行記錄,如果不是ID,它不知道有多少記錄,其實query的時間并不多,但是取結果集的地方就很慢(特别是第二次取結果集),就一直等。

為什麼用while這樣的方式也是沒有辦法,它沒提供一個類似 result_num這樣的方法不知道查詢出來的結果集有多少行資料,隻能一行行讀出來,不得不說這樣的話對效率确實堪憂。

總體來說,如果你的邏輯不那麼複雜,而且你希望得到一個效率還不錯但是讀多寫少,能為mysql分憂解難的場景解決方案,那用這個還是不錯的。

想了一下可以這樣設計今後的資料落地方案

1.資料量很小,但是很碎,可以用 xattr 擴充屬性(4000字元左右)

2.資料量有,但是還是希望能快速,可以用file json_encode(igbinary_serialize)等方式(适合10000條資料以下的場景)

3.資料量上來了(超過10萬),但是還是希望快速,少占用mysql資源,可以采用sqlite3(高速寫入讀取,讀多寫少,相當于資料緩存)。我們可以定義和mysql一樣的資料庫結構,然後在上線前同步資料進來,相當于緩存預熱,作為臨時存儲倉庫

4.資料量非常大(超過百萬),真的需要永久存儲落地,采用mysql方式存儲,這裡面有成熟的關系型資料庫的各種方案。