距離上次接觸sqlite3已經快一年了,去年這篇文章講跟着菜鳥教程學python操作sqlite3,https://www.cnblogs.com/lizhaoyao/p/13717381.html
現在回頭看看,在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方式存儲,這里面有成熟的關系型數據庫的各種方案。
其實本質上來說 sqlite3 也是讀寫文件方式的,只不過有一層接口支持規范化並實現了SQL模型,在項目初期或者某些邊緣業務用這個性價比很高的(只需要寫一個很基礎的sqlite3操作類就相當於有了model層)。
我們不要小看了php操作文件數據的速度,其讀取和寫入都是非常高效率的(不然文件緩存為什么那么好用呢?),當然隨着文件增大,數據變多,其效率會越來越慢,所以建議控制文件大小在5M左右(和機器性能有關系),條數控制在10000條內。
就實際業務而言,中小企業的數據大部分表的數據是不會破萬,破十萬的,只有少部分重要的表會增長到百萬,所以用這個能迅速降低mysql的壓力,在重要數據接口上面提高其吞吐量!