使用嵌入式数据库

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Tair(兼容Redis),内存型 2GB
简介: 【5月更文挑战第12天】SQLite是一个轻量级、稳定的进程内数据库它支持WAL日志模式以提高读写性能,允许设置繁忙超时和启用外键约束。内置5种数据类型,如INTEGER、REAL、TEXT、BLOB和NULL。适 SQLite适合嵌入式应用和读取密集型任务,但不适用于高度并发的写操作或需要多进程协作的场景。

1 简介

Sqlite 在 2000,8 月发布进程内数据库,非常稳定,安全. 现在已经发展到了 sqlite3 。

question_ans.png

2 使用嵌入式数据库:sqlite3 配置

1 日志模式配置 SQLite 如何写入事务

WAL write ahead log 提前写日志安全写入磁盘

  PRAGMA  journal_model = WAL;   

它将让你获得每个事件的快照,和一些读写性能,允许你同时写入和读取。

同时只能有一个写入器。

2 写超时配置

繁忙超时设置写入事务将等待多长时间开始 ,如果不设置,那么在有其他写入器工作时,将立即失败, 推荐5秒

                PRAGMA busy_timeout = 5000;

3 外键配置 Foreign keys

由于历史原因,默认情况下不强制执行外键, 请使用外键

  PRAGMA forgien_keys = ON;

3 sqlite3 类型系统

5个默认类型

        INTEGER -- integral nunmbers
        REAL -- floating point numbers
        TEXT -- readable text data
        BLOB -- binary data
        NULL -- no data

sqlite3 数据库中的存储内容,每个值都与上面的某一个类型关联,类型定义在表格上 大多没有意义。

STRICT mode 严格模式 在 3.37.0才加入 (2021年底)

        CREATE TABLE t (x INTEGER, Y TEXT);

等同于

       CREAET TABLE t(x,y);

缺失的类型

  TIMESTAMP 时间类型。

SQLite有内建函数转换这几种格式

时间类型 typically stored 通常存储为3个形式

最早的格式ISO 8601,但需要更多空间

                          ISO 8601 /RFC 3339(2000-0101T00:00:00Z) 

unix时间

     Seconds since Unix Epoch(1637621759) 

时间戳

      Julian data(2459541.45578376)  

十进制

      DECIMAL  

4 sqlite3 测试经验

SQLite 可以按内存模式在后端运行,这样避免磁盘读写 访问调用的 延时

    func TestDB(t *testing.T) {
        db, err := sql.Open("sqlite3", ":memory:")
        if err != nil {
            t.Fatal(err)
        }
        defer db.Close()
        ////do things at here
    }

性能指标 go-sqlite3 pgsql

    DROP IF EXIST     -             5681us
    CREATE TABLE      801us        2887us
    INSERT            25us          640us
    SELECT            24us          298us

参考仓库

    github.com/benjohnson/production-sqlite-go
    2.3GHz 8-core intel Core 19 macbook pro

5 并行处理 sqlite3 parallelizing in-memory

使用 testin.T.Parallel() 执行内存模式的sqlite3 并行。

go-sqlite3 有一个全局锁,这将减慢 并行测试。

tailscale 实现可以很好地与 cpu 内核一起扩展。

不同的数据库 之间没有共享机制。

  • 性能

    数据耐用性,可靠性

可靠的复制数据, 数据安全性 ,10万次读写有一次失败

  <-------------------------------->>
  hard drive          EBS(gp3/io1)     EBS io2     S3
  99%                 99.9%            99.999%       99.99999999999%
  • 数据丢失 并非总是灾难性的

在 2017年,Gitlab 丢失了 6小时数据, Postgre 主副 配置,保证损失更小。数据也可能被操作者误删除。

所以在数据可靠性,耐用性,性能 成本之间进行权衡 是有必要的。

6 sqlite 数据持久性存储

sqlite 中的数据持久性

1, 常规备份 .backup, mybackup.db

  命令: sqlite3 my.db ".backup 'mybackup0430.db'"

      Pros   fast cheap hard to mess up # 快速 便宜  不易出错
      Cons  larger data loss 大数据容易丢失
      Backup daily 日常备份 或 每小时发送到 S3
      Use time-based file naming 以时间基线为基础的多份备份 和回滚快照
      B-tree 数据库 压缩较好 compress well

2, 数据可靠性 Litestream 几乎实时的监听数据

     Pros  很小的丢失窗口,便宜
     Cons  比常规备份 操作更复杂
     Continuous   流式备份到 S3,streaming backup to s3
     Automatically 自动化,发生灾难时自动恢复 
     cost: 价格: $0.03/month 

指令: listestream replicate db s3://mybucket/db

3, 基于raft的分布式 共识协议

 Pros优点: 非常耐用 very durable
 Cons缺点:   昂贵,更复杂
 Raft-based: 基于raft 共识协议,Philip 贡献了 rqlite,Canonical贡献了dqlite
 Primary/replica: 主从复制 精简
 Blockchain-based: 以量化费用 为基准
  • 查询性能 performance

大多数数据库 是 以B-tree为 基础,有许多具体优化,但是都有一个类似的性能曲线。
网络延时是一个较大的优化点,特别对于 点查询 和 简单范围查询,SQLite 没有网络功能。

点查询 对比:

  sqlite     18us 微秒
  pg local   171us
  pg AZ       321 us
  pg region    区域 902us

1.6 Sqlite3 扩展

sqlite 没有内建的 水平扩展方案,但它是灵活的,通过分片或每个数据库拥有一个 用户权限 来隔离用户,使用一致的哈希算法 分配用户。

sqlite3 有以下特点

没有额外的依赖
启动和运行速度快
只有很少的配置
要小心 类型系统
时间类型 和 十进制 数字类型 的几个表示方式

并行性能

 支持 内建的内存模式
 支持上千个并发 在使用 t.Parallel() 时
 并行化需要 tailscale的实现版本

可靠性 集群

 备份
 流式备份,使用Litestream
 集群SQLite clustered 使用 dqlite,LiteReplica, 或 Bedrock

单点性能高。
没有讨厌的网络延迟或序列化开销。
随着CPU RAM 开销的增加,垂直扩展。

  • 作为嵌入式数据库 embedded databases

符号ACID标准操作

Extensive 广泛的 SQL支持

全文搜索

支持存储 JSON

7 使用实例

type Database struct {
    DB                  *sql.DB
    Writer              Writer
}

type Writer interface { 
    Do(db *sql.DB, txn *sql.Tx, f func(txn *sql.Tx) error) error
}

type StreamStatements struct {
    db                   *sql.DB
    increaseStreamIDStmt *sql.Stmt
}

type Datasource struct {
    Database
    db       *sql.DB
    writer   Writer
    streamID StreamStatements
}

type Base struct {
    Cfg                  *config.Global   //Version int `yaml:"version"`
    Database               *sql.DB
    DatabaseWriter         Writer

} 

type DBOptions struct {
    ConnectionString DataSource `yaml:"connection_string"`
     MaxOpenConnections int `yaml:"max_open_conns"`
     MaxIdleConnections int `yaml:"max_idle_conns"`
     ConnMaxLifetimeSeconds int `yaml:"conn_max_lifetime"`
}

type ExcWriter struct {
    running atomic.Bool
    todo    chan WriterTask
}

func NewExcWriter() Writer {
    return &ExcWriter{
        todo: make(chan ExcWriter),
    }
}

 type WriterTask struct {
    db   *sql.DB
    txn  *sql.Tx
    f    func(txn *sql.Tx) error
    wait chan error
}


func NewDatabase(base *Base, dbProperties *DBOptions) (*Datasource, error) {
    var d Datasource
    var err error
    if d.db, d.writer, err = base.DatabaseConnection(dbProperties, NewExcWriter()); err != nil {
        return nil, err
    }
    if err = d.prepare(base.Context()); err != nil {
        return nil, err
    }
    return &d, nil
}

8 小结

1 何时避免使用:

  • 如果需要多方协作,可能需要避免使用sqlite3
  • 经常有长时间运行的写操作 并发也比较高的需要避免sqlite3
  • 有较多事务操作 时,需要避免使用sqlite3. 因为它是 单进程的

    2 什么应用程序适合SQLlite,

  • 嵌入式软件.

  • 并发性的改进使其更通用的程序.非常适合读取频繁的工作负载.

  • 小到中等的请求负载.

      100‘s of requests/sec
    
  • 在大多数应用程序它都是不错的候选 。

资源;

   首页
    github.com/mattn/go-sqlite3

  transpiled 转译库
            modernc.org/sqlite

  底层SQLITE库
            crawshaw.io/sqlite

  进程内SQLite库
            github.com/tailscale/sqlite
目录
相关文章
|
6月前
|
存储 NoSQL API
一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库
一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库
318 0
|
28天前
|
存储 NoSQL API
.NET NoSQL 嵌入式数据库 LiteDB 使用教程
.NET NoSQL 嵌入式数据库 LiteDB 使用教程~
|
4月前
|
Java 测试技术 数据库连接
Spring Boot中的嵌入式数据库使用
Spring Boot中的嵌入式数据库使用
|
6月前
|
存储 SQL Java
软件体系结构 - 嵌入式系统(3)- 嵌入式数据库
软件体系结构 - 嵌入式系统(3)- 嵌入式数据库
96 0
|
6月前
|
关系型数据库 数据库 C++
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
|
6月前
|
SQL 关系型数据库 Shell
嵌入式数据库sqlite3基本命令操作基础(05)
嵌入式数据库sqlite3基本命令操作基础(05)
148 1
|
6月前
|
SQL Serverless 数据库
嵌入式数据库sqlite3子句和函数的使用基础(06)
嵌入式数据库sqlite3子句和函数的使用基础(06)
58 0
|
6月前
|
Java 关系型数据库 MySQL
【五一创作】嵌入式Sqlite数据库【基本语法、Sqlite-JDBC、嵌入到Java程序】
【五一创作】嵌入式Sqlite数据库【基本语法、Sqlite-JDBC、嵌入到Java程序】
|
关系型数据库 MySQL Linux
在嵌入式 Linux 上移植 MySQL 数据库
MySQL 是一个流行的开源关系型数据库管理系统(RDBMS),它可以用于在各种应用程序中存储和管理数据。尽管 MySQL 在大型服务器上广泛使用,但它也可以在嵌入式 Linux 环境中运行,为嵌入式设备提供高效的数据库管理功能。本文将介绍如何在嵌入式 Linux 上移植 MySQL 数据库。
561 0
|
3天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
16 4