January 13, 2022
By: 马海强

sqlite3

  1. 应该知道
  2. sqlite优势
  3. sqlite劣势
  4. 推荐使用sqlite的场景
  5. 推荐使用mysql的场景
  6. 项目中的使用实践
    1. 业务场景的CURD
    2. 可视化工具
    3. 命令行

应该知道

  • SQL : 结构化查询语言
  • RDBMS : 关系数据库管理系统

sqlite优势

  • "无服务器"数据库,完全开源。
  • SQLite非常容易学习和使用。它不需要任何安装和配置,不用管理,启动/停止什么的。
  • SQLite非常灵活,可以在同一个会话上同时处理多个数据库
  • 提供大量的API,SQLite为大多数的编程语言提供了API,PHP、Java、Objective C、Python、.Net语言(Visual Basic,C#)等
  • 跨平台,可移植。单一文件,在UNIX(Linux,Mac OS-X,Android,iOS)和Windows(Win32,WinCE,WinRT)上均可用
  • 内存数据库,发展方向,可以解决磁盘IO瓶颈问题
  • 3.9版本也加入了json的操作

sqlite劣势

  • 并发访问的锁机制 SQLite在并发(包括多进程和多线程)读写方面的性能一直不太理想。数据库可能会被写操作独占,从而导致其它读写操作阻塞或出错。
  • 触发器/存储过程没有
  • SQLite的局限性
    1. 内置的函数比mysql少
在SQLite中,SQL92不支持的特性如下所示:
RIGHT OUTER JOIN: 只实现了LEFT OUTER JOIN
FULL OUTER JOIN:  只实现了LEFT OUTER JOIN
ALTER TABLE:      支持RENAME TABLE和ALTER TABLE的ADD COLUMN variants命令,不支持DROP COLUMN、ALTER COLUMN、ADD CONSTRAINT
Trigger支持:      支持FOR EACH ROW触发器,但不支持FOR EACH STATEMENT触发器
VIEWS:           在SQLite中,视图是只读的,不能在视图中执行DELETE、INSERT或UPDATE语句
GRANT 和 REVOKE:可以应用的唯一的访问权限是底层操作系统的正常文件访问权限

推荐使用sqlite的场景

  • 安卓或 iOS 客户端需要本地存储
  • 本地开发,demo,减少依赖
  • 嵌入式设备和应用软件

推荐使用mysql的场景

虽然sqlite的小巧玲珑,零配置,使用简单,性能对比优势明显,但是普遍认为,以下情形推荐使用MySQL

  • 分布式操作:MySQL 对复制的支持使它成为设置分布式数据库的绝佳选择,如主-辅或主-主架构。
  • 高流量网站:如果一个网站的点击率少于100000次/天的话, SQLite是可以正常运行的. 100000次/天是一个保守的估计,如果访问量大到要考虑分布式,就不用考虑sqlite了。
  • 预期未来的增长:MySQL 对复制的支持有助于促进横向扩展。此外,升级到 MySQL 商业版是一个相对简单的过程,如支持自动分片的 MySQL 群集,该群集是另一个水平扩展过程。
  • 高并发访问:SQLite对于整个数据库文件进行读取/写入锁定. 这意味着如果任何进程读取了数据库中的某一部分, 其他所有进程都不能再对该数据库的任何部分进行写入操作。

项目中的使用实践

  • attach
  • detach
  • 判断是否attach?
  • sql文件
-- 查询task数据库是否已经加载
-- :name task-db-attached? :? :1
select * from pragma_database_list where name = 'task';

-- 加载任务数据库, 如果不存在就会自动创建
-- :name -attach-task-db
-- :command :execute
-- :result :raw
-- :doc Create database and database file(if not exists.)
ATTACH DATABASE "task.db" AS task;

-- 动态卸载数据库
-- :name -detach-task-db
-- :command :execute
-- :result :raw
-- :doc detech task database
DETACH DATABASE task;


-- 动态创建任务数据表
-- :name create-db-table
-- :command :execute
-- :result :raw
-- :doc Create result table for task-id
CREATE TABLE IF NOT EXISTS :i:tbl-name (
    main_task_code TEXT,
    main_func_code INTEGER,
    sub_task_code TEXT,
    sub_func_result_code INTEGER,
    sensor_code TEXT,
    longitude INTEGER,
    latitude  INTEGER,
    altitude  INTEGER,
    monitoring_time BLOB,
    -- data_type TEXT,-- 协议帧/协议帧去头的bf/算法参数/算法结果/ws 目前仅有bf
    frame_label TEXT,
    data BLOB,
    insert_time TEXT default (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', 'localtime'))
  );

-- :name find-all-tables :? :*
-- :doc 查找到task.db中所有的数据表名
SELECT name FROM task.sqlite_master WHERE type='table'

  • .db文件
(require '[conman.core :as conman])

(conman/bind-connection *db* "sql/task_db.sql")

(defn attach-task-db
  "挂载任务数据库"
  []
  (when-not (task-db-attached?)
      (-attach-task-db)))

(defn detach-task-db
  "卸载任务数据库"
  []
   (when (task-db-attached?)
      (-detach-task-db)))

(mount/defstate task-db
  :start (attach-task-db)
  :stop (detach-task-db))

(defn create-table-for-task
  "创建任务数据库表,不能重复"
  [table-name]
  (create-db-table {:tbl-name table-name}))

业务场景的CURD

与其他关系型数据库sql一样,只需要遵从它自己的语法约定和使用它提供的函数即可。

可视化工具

  • Navicat permium
  • Dberver

命令行

SQLite3命令操作大全

Tags: sqlite sql