嵌入式数据库SQLite 3配置使用详细笔记教程

2024-07-03 1208阅读

0、惨痛教训

        随着管理开发的项目体积越来越庞大,产品系统涉及的数据量也越来越多,并且伴随着项目不久就要交付给甲方了。如果项目的数据信息没有被妥善管理,后期设备的运行状态、操作状况等数据流信息不能被溯源,当出现了一些特殊意外时,就会导致对于故障信息不能迅速准确的追踪,甚至会被甩锅、推卸责任,白白当了冤大头。因此对于嵌入式项目中,其产品运行时的数据库建立非常有必要,且是迫在眉睫!!!

        目前常用的数据库系统有:MySQL、PostgreSQL、Oracle Database、Microsoft SQL Server、SQLite等。在嵌入式项目中,前面几个数据库显然是不合适的,而SQLite是一个轻量级的数据库管理系统,它包含在一个C库中,提供了零配置、无服务器、事务性的SQL数据库引擎。所以SQLite的特点使其非常适合嵌入式系统、移动设备、小型项目或者作为应用程序的本地数据库使用。本文选用了嵌入式数据库SQLite3进行配置和讲解。

1、Sqlite3环境配置

(1)、下载安装SQLite库

根据目标系统平台,下载sqlite源码,或下载官方提供的已经编译好的库。本文目标平台是Windows11 64位平台,进入SQLite Download Page的主页,选择需要的库版本(Windows)。

嵌入式数据库SQLite 3配置使用详细笔记教程

下载的压缩包一共有如下所示的三个:

sqlite-dll-win-x64-3450300.zip

sqlite-dll-win-x86-3450300.zip

sqlite-tools-win-x64-3450300.zip

嵌入式数据库SQLite 3配置使用详细笔记教程

(2)、解压下载的文件

        本文中将对应的Sqlite库文件解压到了,C:\Program Files\sqlite路径下。

嵌入式数据库SQLite 3配置使用详细笔记教程

(3)、添加库路径到环境变量

        根据下图所示的步骤,进入系统属性-->环境变量-->系统变量-->编辑环境变量,将路径加入到环境变量中。

嵌入式数据库SQLite 3配置使用详细笔记教程

(4)、检查数据库安装状态

        打开Windows的命令行,输入sqlite3,有类似如下的数据信息说明库安装成功,后续只需在程序代码中,将库加入到工程代码中即可。

嵌入式数据库SQLite 3配置使用详细笔记教程

(5)、SQLiteStudio工具

        如果有可视化分析数据需求、推荐使用下载:SQLiteStudio嵌入式数据库SQLite 3配置使用详细笔记教程

2、SQLite3基础

        SQL(Structured Query Language)是一种结构化查询语言,SQL 是一种专门用来与数据库通信的语言。

        不同的数据库管理系统在其实践过程中都对 SOL 规范作了某些改编和扩充。故不同数据库管理系统之间的 SOL语言不能完全相互通用。

        以下是SQLite的一些关键特点:

  • 零配置: SQLite不需要安装或者管理服务器进程。启动一个使用SQLite的应用程序时,数据库文件会自动创建(如果尚不存在),并且直接通过程序访问。
  • 轻量级: SQLite的代码量小,资源消耗少,对硬件要求很低。这使得它非常适合资源有限的环境,如手机、平板电脑或微型设备。
  • 跨平台: SQLite兼容几乎所有主流的操作系统,包括Windows、Linux、Unix、Android、iOS等。
  • 服务器less: 由于SQLite是嵌入式的,没有单独运行的数据库服务器进程,数据直接存储在文件中。这简化了部署和维护过程。
  • 事务处理: SQLite支持ACID(原子性、一致性、隔离性、持久性)事务,确保数据的完整性。
  • SQL标准兼容: 虽然SQLite有自己的SQL方言,但它大体上遵循ANSI SQL标准,支持大多数标准SQL语句。
  • 单一文件存储: SQLite数据库完全存储在一个磁盘文件中,这使得备份和迁移数据库变得非常简单,只需复制该文件即可。
  • 动态类型: SQLite具有弱类型特性,允许更灵活的数据存储,但也可能需要开发者更加注意数据类型的处理。
  • 广泛使用: SQLite被许多应用程序和操作系统采用,包括浏览器(如Firefox)、操作系统组件、手机应用等,是世界上最广泛部署的数据库引擎之一。

            有个重要的点值得注意,SQLite 是不区分大小写的,但也有一些命令是大小写敏感的,比如 GLOB 和 glob 在 SQLite 的语句中有不同的含义。一般数据采用固定的静态数据类型,而 SOLite 采用的是动态数据类型,会根据存入值自动判断。

    SQLite 存储类:SOLite 具有以下五种基本数据类型

    (1)integer:带符号的整型(最多64位)。

    (2)real:8字节表示的浮点类型。

    (3)text:字符类型,支持多种编码(如 UTF-8、UTF-16),大小无限制。

    (4)blob:任意类型的数据,大小无限制。 BLOB(binary large obiect)二进制大对象,使用二进制保存数据。

    (5)null:表示空值

    SQLite 亲和类型(Affinity)及类型名称

    下表列出了当创建 SQLite3 表时可使用的各种数据类型名称,同时也显示了相应的亲和类型:

    数据类型

    亲和类型

    • INT
    • INTEGER
    • TINYINT
    • SMALLINT
    • MEDIUMINT
    • BIGINT
    • UNSIGNED BIG INT
    • INT2
    • INT8

    INTEGER

    • CHARACTER(20)
    • VARCHAR(255)
    • VARYING CHARACTER(255)
    • NCHAR(55)
    • NATIVE CHARACTER(70)
    • NVARCHAR(100)
    • TEXT
    • CLOB

    TEXT

    • BLOB
    • 未指定类型

    BLOB

    • REAL
    • DOUBLE
    • DOUBLE PRECISION
    • FLOAT

    REAL

    • NUMERIC
    • DECIMAL(10,5)
    • BOOLEAN
    • DATE
    • DATETIME

    NUMERIC

    SQLite 语句:所有的 SQLite 语句可以以任何关键字开始,如 SELECT、INSERT、UPDATE、DELETE、ALTER、DROP 等,所有的语句以分号 ; 结束。

    3、SQLite3基本语法

    (1)、创建数据库

    //打开数据库,如不存在则会创建数据库
    int ret = sqlite3_open("project_data.db", &db);
    if( ret )
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        exit(-1);
    }
    fprintf(stderr, "Opened database successfully\n");

    (2)、创建表

    //CREATE TABLE 告诉数据库系统创建一个新表的关键字。CREATE TABLE 语句后跟着表的唯一的名称或标识。
    CREATE TABLE database_name.table_name(
       column1 datatype  PRIMARY KEY(one or more columns),
       column2 datatype,
       column3 datatype,
       .....
       columnN datatype,
    );
    char table_name[200] = {0};
    char *err_msg = NULL;
    snprintf(table_name, sizeof(table_name), "create table if not exists camera(time_stamp integer primary key, action text, x integer, y integer, z integer, vx integer, vy integer, vz integer, time integer);");
    int ret = sqlite3_exec(db, table_name, NULL, NULL, &err_msg);
    if(ret){
        fprintf(stderr, "create table err:%s\n", err_msg);
        return -1;
    }
    fprintf(stderr, "create table successfully\n");

    (3)、删除表

    //SQLite 的 DROP TABLE 语句用来删除表定义及其所有相关数据、索引、触发器、约束和该表的权限规范。
    //DROP TABLE 语句的基本语法如下。
    DROP TABLE database_name.table_name;
    char table_name[200] = {0};
    char *err_msg = NULL;
    snprintf(table_name, sizeof(table_name), "DROP TABLE database_name.table_name;");
    int ret = sqlite3_exec(db, table_name, NULL, NULL, &err_msg);
    if(ret){
        fprintf(stderr, "delete table err:%s\n", err_msg);
        return -1;
    }
    fprintf(stderr, "delete table successfully\n");

    (4)、插入数据

    INSERT INTO 语句有两种基本语法,如下所示:
    INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]  VALUES (value1, value2, value3,...valueN);//在这里,column1, column2,...columnN 是要插入数据的表中的列的名称
    或
    INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);
    //确保值的顺序与列在表中的顺序一致。
    char table_value[200] = {0};
    int ret = 0;
    char *err_msg = NULL;
    snprintf(table_value, sizeof(table_value),"insert into camera values(%lld, '%c', %d, %d, %d, %d, %d, %d, %d);", get_current_timestamp_ms(), action, x, y, z, vx, vy, vz, time);
    ret = sqlite3_exec(db, table_value, NULL, NULL, &err_msg);
    if(ret)
    {
        fprintf(stderr, "insert value to table err:%s\n", err_msg);
        return -1;
    }
    fprintf(stderr, "insert value to table successfully\n");

    (5)、查询数据

    //SQLite 的 SELECT 语句用于从 SQLite 数据库表中获取数据,以结果表的形式返回数据。这些结果表也被称为结果集。
    //SQLite 的 SELECT 语句的基本语法如下:
    SELECT column1, column2, columnN FROM table_name;//在这里,column1, column2...是表的字段,他们的值即是您要获取的。
    SELECT * FROM table_name;    //获取所有可用的字段
    char *err_msg = NULL;
    sprintf(sql, "select * from table_value;");
    ret = sqlite3_exec(db, sql, NULL, NULL, &err_msg);   //执行 SQL 命令的快捷方式
    if(ret)
    {
        fprintf(stderr, "Can't select sqlite value: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    (6)、删除数据

    //SQLite 的 DELETE 查询用于删除表中已有的记录。可以使用带有 WHERE 子句的 DELETE 查询来删除选定行,否则所有的记录都会被删除。
    //带有 WHERE 子句的 DELETE 查询的基本语法如下:
    DELETE FROM table_name
    WHERE [condition];
    //可以使用 AND 或 OR 运算符来结合 N 个数量的条件。
    char *err_msg = NULL;
    sprintf(sql, "DELETE FROM camera WHERE time_stamp = 123456789;");
    ret = sqlite3_exec(db, sql, NULL, NULL, &err_msg);   //执行 SQL 命令的快捷方式
    if(ret)
    {
        fprintf(stderr, "Can't DELETE sqlite data: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    (7)、修改数据

    //SQLite 的 UPDATE 查询用于修改表中已有的记录。可以使用带有 WHERE 子句的 UPDATE 查询来更新选定行,否则所有的行都会被更新。
    //带有 WHERE 子句的 UPDATE 查询的基本语法如下:
    UPDATE table_name
    SET column1 = value1, column2 = value2...., columnN = valueN
    WHERE [condition];
    char *err_msg = NULL;
    sprintf(sql, "UPDATE camera SET action = 't' WHERE time_stamp = 123456789;");
    ret = sqlite3_exec(db, sql, NULL, NULL, &err_msg);   //执行 SQL 命令的快捷方式
    if(ret)
    {
        fprintf(stderr, "Can't DELETE sqlite data: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    4、SQLite3代码

    #include 
    #include 
    #include 
    #include 
    #include 
    int database_init();
    int write_motor_info_to_database(sqlite3 *db, int motor_id, double target_pos, double real_pos, double real_speed, double real_current);
    int write_camera_info_to_database(sqlite3 *db, char action, int x, int y, int z, int vx, int vy, int vz, int time);
    long long get_current_timestamp_ms(void); 
    int main(void)
    {
        printf("sqlite3 database test!\n");    
        database_init();
        return 0;
    }
    /**
      * @brief  数据库初始化
      * @param  NONE
      * @retval 成功返回0, 失败返回-1
      */
    int database_init(void)  
    {
        int ret = -1;
        sqlite3 *db;
        char *err_msg = NULL;
        char database_name[128] = {0};
        //获取当前时间
        struct tm t; 
        time_t now;
        time(&now);
        localtime_s(&t, &now);
        snprintf(database_name, sizeof(database_name),"%02d%02d%02d.db", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
        printf("date:%s\n", database_name);
       //打开数据库
        ret = sqlite3_open(database_name, &db);
        if( ret )
        {
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return -1;
        }
        fprintf(stderr, "Opened database successfully\n");
        char table_name[200] = {0};
        //时间戳 目标位置 实际位置 实际速度 实际电流
        //create table if not exists motor0 (time_stamp integer primary key, target_pos real, real_pos real, real_speed real, real_current, real);
        for(int motor_id = 0; motor_id  
    

    参考代码运行结果

    嵌入式数据库SQLite 3配置使用详细笔记教程

    使用可视化工具SQLiteStudio,对SQLite3数据库进行查看。

    嵌入式数据库SQLite 3配置使用详细笔记教程

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]