本帖最后由 小小毛 于 2020-12-27 22:10 编辑

SQLite 简介
     本教程帮助您了解什么是 SQLite,它与 SQL 之间的不同,为什么需要它,以及它的应用程序数据库处理方式。
SQLite是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite是一个增长最快的数据库引擎,这是在普及方面的增长,与它的尺寸大小无关。SQLite 源代码不受版权限制。

什么是 SQLite?
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。
就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
为什么要用 SQLite?

  • 不需要一个单独的服务器进程或操作的系统(无服务器的)。

  • SQLite 不需要配置,这意味着不需要安装或管理。

  • 一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。

  • SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。

  • SQLite 是自给自足的,这意味着不需要任何外部的依赖。

  • SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。

  • SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。

  • SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。

  • SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。

历史

  • 2000 -- D. Richard Hipp 设计 SQLite 是为了不需要管理即可操作程序。

  • 2000 -- 在八月,SQLite1.0 发布 GNU 数据库管理器(GNU Database Manager)。

  • 2011 -- Hipp 宣布,向 SQLite DB 添加 UNQl 接口,开发 UNQLite(面向文档的数据库)。

SQLite 局限性
在 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 命令
与关系数据库进行交互的标准 SQLite 命令类似于 SQL。命令包括 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。这些命令基于它们的操作性质可分为以下几种:
DDL - 数据定义语言
命令
描述
CREATE创建一个新的表,一个表的视图,或者数据库中的其他对象。
ALTER修改数据库中的某个已有的数据库对象,比如一个表。
DROP删除整个表,或者表的视图,或者数据库中的其他对象。
DML - 数据操作语言
命令
描述
INSERT创建一条记录。
UPDATE修改记录。
DELETE删除记录。
DQL - 数据查询语言
命令
描述
SELECT从一个或多个表中检索某些记录。
安装
在 C/C++ 程序中使用 SQLite 之前,我们需要确保机器上已经有 SQLite 库。可以查看 SQLite 安装章节了解安装过程。
C/C++ 接口 API
以下是重要的 C&C++ / SQLite 接口程序,可以满足您在 C/C++ 程序中使用 SQLite 数据库的需求。如果您需要了解更多细节,请查看 SQLite 官方文档。
序号
API & 描述
1sqlite3_open(const char *filename, sqlite3 **ppDb)
该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。
如果 filename 参数是 NULL 或 ':memory:',那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。
如果文件名 filename 不为 NULL,那么 sqlite3_open() 将使用这个参数值尝试打开数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。
2sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
该例程提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成。
在这里,第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。
sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。
3sqlite3_close(sqlite3*)
该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。
如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。
连接数据库
下面的 C 代码段显示了如何连接到一个现有的数据库。如果数据库不存在,那么它就会被创建,最后将返回一个数据库对象。
#include <stdio.h>
  • #include <sqlite3.h>
  • int main(int argc, char* argv[])
  • {
  •    sqlite3 *db;
  •    char *zErrMsg = 0;
  •    int rc;
  •    rc = sqlite3_open("test.db", &db);
  •    if( rc ){
  •       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
  •       exit(0);
  •    }else{
  •       fprintf(stderr, "Opened database successfully\n");
  •    }
  •    sqlite3_close(db);
  • }
  • 复制代码
    现在,让我们来编译和运行上面的程序,在当前目录中创建我们的数据库 test.db。您可以根据需要改变路径。
    $gcc test.c -l sqlite3
  • $./a.out
  • Opened database successfully
  • 复制代码
    如果要使用 C++ 源代码,可以按照下列所示编译代码:
    $g++ test.c -l sqlite3在这里,把我们的程序链接上 sqlite3 库,以便向 C 程序提供必要的函数。这将在您的目录下创建一个数据库文件 test.db,您将得到如下结果:
    -rwxr-xr-x. 1 root root 7383 May  8 02:06 a.out
  • -rw-r--r--. 1 root root  323 May  8 02:05 test.c
  • -rw-r--r--. 1 root root    0 May  8 02:06 test.db
  • 复制代码
    创建表
    下面的 C 代码段将用于在先前创建的数据库中创建一个表:
    #include <stdio.h>
  • #include <stdlib.h>
  • #include <sqlite3.h>
  • static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  •    int i;
  •    for(i=0; i<argc; i++){
  •       printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  •    }
  •    printf("\n");
  •    return 0;
  • }
  • int main(int argc, char* argv[])
  • {
  •    sqlite3 *db;
  •    char *zErrMsg = 0;
  •    int  rc;
  •    char *sql;
  •    /* Open database */
  •    rc = sqlite3_open("test.db", &db);
  •    if( rc ){
  •       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
  •       exit(0);
  •    }else{
  •       fprintf(stdout, "Opened database successfully\n");
  •    }
  •    /* Create SQL statement */
  •    sql = "CREATE TABLE COMPANY("  \
  •          "ID INT PRIMARY KEY     NOT NULL," \
  •          "NAME           TEXT    NOT NULL," \
  •          "AGE            INT     NOT NULL," \
  •          "ADDRESS        CHAR(50)," \
  •          "SALARY         REAL );";
  •    /* Execute SQL statement */
  •    rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
  •    if( rc != SQLITE_OK ){
  •    fprintf(stderr, "SQL error: %s\n", zErrMsg);
  •       sqlite3_free(zErrMsg);
  •    }else{
  •       fprintf(stdout, "Table created successfully\n");
  •    }
  •    sqlite3_close(db);
  •    return 0;
  • }
  • 复制代码
    上述程序编译和执行时,它会产生以下结果:
    Opened database successfully
  • Callback function called: ID = 1
  • NAME = Paul
  • AGE = 32
  • ADDRESS = California
  • SALARY = 20000.0
  • Callback function called: ID = 3
  • NAME = Teddy
  • AGE = 23
  • ADDRESS = Norway
  • SALARY = 20000.0
  • Callback function called: ID = 4
  • NAME = Mark
  • AGE = 25
  • ADDRESS = Rich-Mond
  • SALARY = 65000.0
  • Operation done successfully
  • 复制代码