美文网首页
sqlite学习5

sqlite学习5

作者: 我是花老虎 | 来源:发表于2016-07-30 00:07 被阅读96次

    SQLite Design and Concepts

    API

    分为两大类

    1. core API. 基本的SQL操作
    2. extension API. 创建自定义的SQL操作。

    基本数据结构

    需要了解的组成部分有连接、statments、B树、pager。
    为了写好SQLite代码,需要了解的基本概念,API、事务和锁。

    连接和statments

    这两种数据结构和查询语句的基础。一个连接表示对数据库的一个连接,也是一个事务上下文。statments由这些连接产生。statments在内部由VDBE字节码表示。

    B-tree and pager

    每个数据库连接可以有多个数据库。每一个数据库对象有一个B-tree对象,每一个B-tree对象有一个pager对象。
    pager的工作包括把page从磁盘导入到内存中、写数据库、管理事务、处理锁和从crash中恢复等。
    一个数据库连接中是在事务中操作,一个数据库连接不会同时有两个事务。

    Core API

    两种方式来执行SQL语句。

    1. prepared query. SQLite执行命令的最终方式。包括三个阶段
      1. preparation
      2. execution
      3. finalization
    2. wrapped query

    连接数据库

    sqlite3_open()传入:memory:或空字符串作为数据库的名称,会创建内存中的数据库。
    如果数据库的pagesize和操作系统的pagesize相同,会提高IO效率。

    运行prepared query

    • prepation:把字符串转化为VDBE字节码。sqlite3_prepare_v2()生成sqlite3_stmt句柄,包括编译好的字节码和需要执行命令和迭代结果集的所有资源。
    • execution:sqlite3_step使VDBE单步执行字节码。首次调用会获取某种锁。
    • finalization:sqlite3_finalize()关闭statment,释放相关资源。

    使用参数化的SQL

    包括两种参数绑定

    1. positional
    2. named

    使用参数绑定的优势

    1. 不需要编译,可以执行statment多次。只需要reset,然后重新bind,运行。
    2. 自动处理好转义字符,避免数据库注入和语法错误。

    运行wrapped query

    sqlite3_exec()sqlite3_get_table()
    exec()解析命令,识别出单独的语句,并依次处理。

    处理错误

    sqlite3_errcode()返回最后执行函数的错误码。使用sqlite3_errmsg()提供最后错误的描述。

    格式化SQL语句

    sqlite3_mprintf().类似sprintf(),%q%s类似,不过会把每一个单引号变为连续的两个,防止数据库注入。%Q会为字符串首尾加上单引号,空指针会变成NULL

    操作控制

    使用注册filter或callback函数来达到在特定事件发生时会被monitor,control。
    有三个hook函数

    1. sqlite3_commit_hook()
    2. sqlite3_rollback_hook()
    3. sqlite3_update_hook()
    4. wal_hook()(3.7版本中)

    使用多线程

    shared cache mode:使用多个一个线程来管理多个SQL连接,这些连接共享page cache,降低了server的内存使用。

    extension API

    事务

    事务的生命周期

    1. 在事务下究竟是什么在运行。
      在每个数据连接中的每个数据库对象,有一个B-Tree和pager对象。pager管理事务、锁、缓存、崩溃恢复。
    2. 事务何时开始,何时结束,何时开始影响其他数据库连接。
      可以短到一个语句,可以长到直到你命令终结。一个操作默认在autocommit模式,即每一个命令在一个事务中运行。何时影响和锁的状态有关。

    锁的状态

    每一个事务以unlocked,reserved,exclusize锁状态开始

    读事务

    两次读操作
    使用事务:unlocked->pending->shared->unlocked
    不使用事务:unlocked->pending->shared->unlocked->pending->shared->unlocked
    不适用事务,在两次读之间数据可能会改变

    写事务

    每一个操作,读或者写,都必须经过unlocked->pending->shared. pending是gateway lock。

    reserved state

    当要向数据库中写入时,需要从shared到reserved状态。到reserved状态后,可以把改变写到本地缓存,而不是数据库中。
    进入reserved状态后,pager初始化rollback journal,是用于回滚和crash recovery的文件。实际是为更改前的数据库内容。
    在reserved状态中,需要pager维护三种pages:改变的pages(存在page cache中),未改变的pages(读出的没有改变的page)以及日志pages(不在page cache中,而是在B-Tree改变page前写入joural)。

    pending state

    pending lock是gateway lock,保证不会有锁从unlocked到shared状态。

    exclusive state

    此状态下,主要工作是把改变的page从page cache冲入数据库文件。此时pager真正开始改变数据库。
    在写入数据库之前,先确保日志文件已经被写入磁盘。
    日志是系统崩溃或掉电后,日志是恢复数据库的唯一方法。
    日志文件在commit之后才会被清除。

    自动提交和效率

    自动提交效率不高,因为每个语句都要获取锁。而且语句之间可能会被改变。

    调整page cache

    转向互斥状态

    一般来说,当pager不能存储更多数据时,会从reserved状态转向互斥状态。实际上,有soft limit和hard limit。
    soft limit是指page cache首次被占满,此时包括改变的和未更改page的混合。pager会移除未更改的page,如此重复,直到所有的都被更改的page占满。此时page cache都是已更改的page,进入hard limit,不得不转向互斥状态。
    cache_size调整page cache的大小。

    决定page cache的大小

    利用sqlite3_analyer

    等待锁

    使用busy handler

    sqlite3_busy_timeout()

    使用正确的事务

    写操作使用begin immediate

    相关文章

      网友评论

          本文标题:sqlite学习5

          本文链接:https://www.haomeiwen.com/subject/fvozjttx.html