基于嵌入式linux的数据库:SQLite

news/2025/2/25 16:45:44

数据库基本概念

1. 数据(Data) 
      能够输入计算机并能被计算机程序识别和处理的信息集合。
2. 数据库 (Database)         
      数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合。
          注:数据库管理系统(DataBase Management  System)------DBMS

数据库管理系统( DBMS ) 
	       DBMS是数据库系统中对数据进行统一管理和控制的软件系统。
	(1) 数据库定义功能。(Data Definition)
	(2) 数据库操纵功能。 (Data Manipulation)
	(3) 数据库运行控制功能。 (Data Control)
	(4) 数据通信功能。 (Data  Communication)
	(5) 支持存取海量数据。 (Mass Data)

 文件管理阶段:
      优点:
	(ⅰ)数据可长期保存          
	(ⅱ)能存储大量数据
	   缺点: 
	 (ⅰ)数据冗余度(redundancy)大,
	    	数据一致性(consistency)、
			完整性(integrity)难以维持。
	 (ⅱ)数据与程序缺乏高度独立性。

数据库系统阶段
	  (ⅰ)数据组织结构化。
	  (ⅱ)数据冗余度比较小,易扩充。
	  (ⅲ)具有较高的数据与程序之间的独立性。
	  (ⅳ)统一的数据控制。

常用的数据库

大型数据库
   	Oracle公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作系统平台。目前Oracle关系数据库产品的市场占有率名列前茅。
  	IBM 的DB2是第一个具备网上功能的多媒体关系数据库管理系统, 支持包括Linux在内的一系列平台。
中型数据库 
	Server是微软开发的数据库产品,主要支持windows平台
小型数据库
   	mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,2008年被Sun公司收购。开放源码

linux_38">基于嵌入式linux数据库

基于嵌入式linux数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB。
    Firebird是关系型数据库,功能强大,支持存储过程、SQL兼容等。
	SQLite关系型数据库,体积小,支持ACID事务。
	Berkeley DB中并没有数据库服务器的概念,它的程序库直接链接到应用程序中。 
	eXtremeDB是内存数据库,运行效率高。

SQLite3

SQLite的源代码是C,其源代码完全开放。SQLite第一个Alpha版本诞生于2000年5月。 他是一个轻量级的嵌入式数据库。
SQLite有以下特性:
     零配置一无需安装和管理配置;
     储存在单一磁盘文件中的一个完整的数据库数据库文件可以在不同字节顺序的机器间自由共享;
     支持数据库大小至2TB;
     足够小,全部源码大致3万行c代码,250KB;
     比目前流行的大多数数据库对数据的操作要快;
使用注意事项
	 需要在线下载或者安装离线包
	 在编译时需要链接相应的库  -lsqlite3

SQLite数据库采用了模块化设计,由8个独立的模块构成,这些独立模块又构成了三个主要的子系统,模块将复杂的查询过程分解为细小的工作进行处理:

SQLite<a class=数据库" />

安装方式

在线安装:

sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev

离线安装:

1> 先把安装包移动到家目录中
   sqlite-autoconf-3240000.tar.gz

2> 执行解压命令
   sudo tar -xvf sqlite-autoconf-3240000.tar.gz
            
3> 切换到解压出来的目录
   cd sqlite-autoconf-3240000/
       
4> 执行以下命令:环境配置的可执行文件,完善当前环境配置的修改
   sudo ./configure
       
5> 执行以下命令
   sudo make

6> 执行以下命令
   sudo make install

7> 测试是否正常安装
   farsight@Ubuntu18:~/sqlite-autoconf-3240000$ cd ~
   farsight@Ubuntu18:~$ ls
   Downloads  shared     test.c
   a.out      mnt        sqlite-autoconf-3240000         Videos
   app        Music      sqlite-autoconf-3240000.tar.gz
   Desktop    Pictures   Templates
   Documents  Public     test
   
   farsight@Ubuntu18:~$ sqlite3 info.db
   SQLite version 3.24.0 2018-06-04 19:24:41
   Enter ".help" for usage hints.
   sqlite> .quit
   /**
       退出方式:
       1> 三次CTRL+C
       2> .quit加回车键
   **/              

在这里插入图片描述
在这里插入图片描述

备注:info.db实际上就是一张表:
在这里插入图片描述

SQLite数据库的使用方式

sqlite3_110">1. sqlite3命令
.databases	 	    列出数据库文件名
.tables ?PATTERN? 	列出?PATTERN?匹配的表名
.import FILE TABLE	将文件中的数据导入的文件中
.dump ?TABLE? 		生成形成数据库表的SQL脚本
.output FILENAME 	将输出导入到指定的文件中
.output stdout 		将输出打印到屏幕
.mode MODE ?TABLE?  设置数据输出模式(csv,html,tcl…	
.nullvalue STRING	用指定的串代替输出的NULL串
.read FILENAME		执行指定文件中的SQL语句
.schema ?TABLE?	    打印创建数据库表的SQL语句 
.separator STRING 	用指定的字符串代替字段分隔符
.show 			    打印所有SQLite环境变量的设置
.quit 			    退出命令行接口
.head on            打印数据时,展示出表头
.head off           打印数据时,不展示出表头
sqlite3_128">2. sqlite3语句

(…> 表示输入的内容还未结束,需补上;)

手工创建
		使用sqlite3工具,通过手工输入SQL命令行完成数据库创建.
		用户在Linux的命令行界面中输入sqlite3可启动sqlite3工具
代码创建
		在代码中常动态创建数据库
		在程序运行过程中,当需要进行数据库操作时,应用程序会首先尝试打开数据库,此时如果数据库并不存在,程序则会自动建立数据库,然后再打开数据库

在终端下运行sqlite3   <*.db>,出现如下提示符:
SQLite  version  3.7.2
Enter “.help” for instructions
Enter SQL statements terminated with a “;sqlite>

#<*.db> 是要打开的数据库文件。若该文件不存在,则自动创建。
2.1> 针对于表
		2.1.1创建
            //a.普通创建
            原型:create table 表名 (列名 列名类型,列名 列名类型,......);//与C语言定义相反
            例子:create table info (ID int,name char[20],pwd char[20]);
            //b.避免重复创建
            原型:create table if not exists 表名 (列名 列名类型,列名 列名类型,......);
            例子:create table if not exists info (IIDD int,name char[20],pwd char[20]);               
           
        2.1.2删除
            原型:drop table 表名 ;
            例子:drop table info;
            
        2.1.3修改(只能增加项,不能减少)
            原型:alter table 表名 add column 列名 列名类型;
            例子:alter table info add column salary char[20];
            
            alter table 原表名 rename to 新表名;
            alter table test rename to info;
            
        2.1.4查看表
            .table         查看所有表
            .table 表名     查看指定的表
            .schema 表名    查看表的格式
        
        2.1.5在表中删除字段 
			Sqlite中不允许删除字段,可以通过下面步骤达到同样的效果
			sqlite> create table stu as select no, name, score from student
			sqlite> drop table student
			sqlite> alter table stu rename to student

	                
/**增删改查**/
2.2> 针对于数据
		2.2.1增加数据
		   原型:insert into 表名 values (value1, value2,…);//每一列的数值用逗号隔开
		   例子:insert into info values (1, "Tomas","123456","$500000");
		        insert into info values (2, "Alen","666666","$60000");               
		        
		2.2.2查询数据
			//控制查看数据的表头显示与否
			.header on
		
		   //a.查看该表中所有数据
		   原型:select * from 表名;
		   例子:select * from info;
		   
		   //b.查看该表中符合条件的数据
		   原型:select * from 表名 where 条件;(多条件之间用and(与)或者or(或)连接)
		   例子:select * from info where ID == 1;//单条件
		        select * from info where ID == 1 or pwd == "666666";//多条件
		        select * from info where ID == 1 and pwd == "888888";//多条件                     
		        
		2.2.3删除数据         
		   原型:delete from 表名 where 条件;
		   例子:delete from info where pwd == "888888";               
		   
		2.2.4修改数据
		   原型:update 表名 set 列名 = 数值,列名 = 数值 ...... where 条件;             
		   例子:update info set name = "laoguo",pwd = "9999" where ID == 2; 

在这里插入图片描述

3.SQLite3的API函数
(
    程序中需要包含相应的头文件 #include <sqlite3.h>
    
    编译时需要链接相应的库 -lsqlite3
)

3.1>打开数据库
    int sqlite3_open(char *path,sqlite3 **db);
    /**********************************************************************
    @brief:     打开sqlite数据库
    
    @path:     数据库文件路径(如果文件不存在则创建,文件存在则打开。)

    @db:       指向sqlite句柄的指针 
        
    @retval:    成功:返回SQLITE_OK(0)
                失败:返回错误码(非零值)
   
   **********************************************************************/    

3.2>执行SQLite3语句
    int sqlite3_exec(sqlite3 *db, const  char  *sql,  sqlite3_callback callback, void * arg,  char **errmsg);
    /**********************************************************************
    @brief:     执行SQL操作
    
    @db:       数据库句柄

    @sql:      SQL语句
    
    @callback:  回调函数的函数指针
    
    @arg:      给回调函数传的参数
    
    @errmsg:   错误信息指针的地址
        
    @retval:    成功:返回SQLITE_OK(0)
                失败:返回错误码(非零值)
   
   	**********************************************************************/    
	typedef int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);

   /**********************************************************************
    @brief:     如果使用select语句查表的数据,会调用到该回调函数
    
    @para:     给回调函数传过来的参数

    @f_num:    回调函数中查询的表中的列的数量
    
    @f_value:   表中的具体的数据
    
    @f_name:   表中的具体的表头(列名)
            
    @retval:    成功:返回SQLITE_OK(0)
                失败:返回错误码(非零值)
   
    /**
        使用回调函数时,要在最后加上return 0;  ,否则回调函数只会调用一次
    **/  
    /**********************************************************************/   
		例如:int LoadMyInfo(void * para, int n_column, char ** column_value, char ** column_name)
		para是在 sqlite3_exec 里传入的 void * 参数,通过para参数,可以传入带有控制功能的数据
		
		n_column是这一条记录有多少个字段 (即这条记录有多少列)
		
		char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组,每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以\0结尾)
		
		char ** column_name 跟 column_value是对应的,表示这个字段的字段名称
		
		说明:回调函数必须定义为上面这个函数的类型。
	
3.3>关闭数据库
		int sqlite3_close(sqlite3 *db);
		/**********************************************************************
		@brief:    关闭sqlite数据库
		@db:       数据库句柄
		@retval:    成功:返回SQLITE_OK(0)
		           	失败:返回错误码(非零值)
		
		**********************************************************************/   
3.4>获得错误信息
		const char *sqlite3_errmg(sqlite3 *db);
		/**********************************************************************
		@brief:     关闭sqlite数据库
		@db:       数据库句柄
		@retval:    返回错误信息            
		**********************************************************************/   
sqlite3_297">完整操作sqlite3数据表的代码
#include <sqlite3.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int i;

int CheckMsg(void *para,int n_column,char **column_value,char **column_name)
{
    //printf("para:%s\n",(char *)para);

    static int flag = 0;//利用static在修饰局部变量时只会初始化一次的特点,控制打印表头的次数为1次
    if(!flag)
    {
		for(i = 0;i < n_column;i++)
			printf("%s|",column_name[i]);//column_name[0] = ID,column_name[1] = name,column_name[2] = pwd; 

		printf("\n");
		flag = 1;
    }

    for(i = 0;i < n_column;i++)
		printf("%s|",column_value[i]);

		printf("\n");

    return 0;
}

int main(void)
{
    sqlite3 *db;//制作句柄用于后续操作
    char *errmsg;	
    //打开数据库文件
    int ret = sqlite3_open("info.db", &db);
    if(ret != SQLITE_OK)
    {
		perror("sqlite3 open");
		exit(1);
    }

    //执行sql语句,创建一张表
    char sql[256] = "create table if not exists info (ID int,name char[20],pwd char[20]);";
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
		perror("sqlite3 exec");
		printf("errmsg:%s\n",errmsg);
		exit(1);
    }

    //执行sql语句,将数据写入到表中
    bzero(sql,sizeof(sql));
    strcpy(sql,"insert into info values (1, \"Tomas\",\"123456\");");
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
		perror("sqlite3 exec");
		printf("errmsg:%s\n",errmsg);
		exit(1);
    }

    bzero(sql,sizeof(sql));
    strcpy(sql,"insert into info values (2, 'Alen', '666666');");
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
		perror("sqlite3 exec");
		printf("errmsg:%s\n",errmsg);
		exit(1);
    }

    //查询数据,需要用到回调函数
    bzero(sql,sizeof(sql));
    strcpy(sql,"select * from info;");
    ret = sqlite3_exec(db, sql, CheckMsg, "数据库查询,启动!", &errmsg);
    if(ret != SQLITE_OK)
    {
		perror("sqlite3 exec");
		printf("errmsg:%s\n",errmsg);
		exit(1);
    }

    //关闭数据库
    if(sqlite3_close(db) != SQLITE_OK)
	{
		fprintf(stderr,"error : %s\n", sqlite3_errmsg(db));
		fprintf(stderr,"error : %s\n", errmsg);
		exit(-1);
	}

    return 0;
}

综上。希望该内容能对你有帮助,感谢!

以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!


http://www.niftyadmin.cn/n/5865720.html

相关文章

GO 进行编译时插桩,实现零码注入

Go 编译时插桩 Go 语言的编译时插桩是一种在编译阶段自动注入监控代码的技术&#xff0c;目的是在不修改业务代码的情况下&#xff0c;实现对应用程序的监控和追踪。 基本原理 Go 编译时插桩的核心思想是通过在编译过程中对源代码进行分析和修改&#xff0c;将监控代码注入到…

网络安全-系统层攻击流程及防御措施

系统层攻击流程涉及多个阶段&#xff0c;攻击者通过逐步渗透以获取控制权或窃取数据。以下是详细的流程及防御措施&#xff1a; 1. 侦察&#xff08;Reconnaissance&#xff09; 信息收集&#xff1a; 主动扫描&#xff1a;使用工具如Nmap、Masscan扫描目标IP、开放端口、服务…

深度学习训练平台建设中的性能优化实践

在当今数据驱动的时代&#xff0c;深度学习已成为人工智能领域的关键技术。然而&#xff0c;深度学习的成功不仅依赖于算法的先进性&#xff0c;还极大地依赖于训练平台的性能和效率。本文将探讨深度学习训练平台建设中的性能优化实践&#xff0c;特别是在任务模板、数据处理、…

pycharm技巧--鼠标滚轮放大或缩小 Pycharm 字体大小

1、鼠标滚轮调整字体 设置 Ctrl 鼠标滚轮调整字体大小 备注&#xff1a; 第一个是活动窗口&#xff0c;即缩放当前窗口 第二个是所有编辑器窗口&#xff0c;即缩放所有窗口的字体 2、插件 汉化包&#xff1a; Chinese Simplified 包

[SWPUCTF 2022 新生赛]ez_rce

打开题目就在线环境&#xff0c;发现只有一句话&#xff1a;真的什么都没有吗 F12查看控制台和源代码也没发现任何信息&#xff0c;然后用虚拟机里面的dirsearch扫一下这个网站就能得到&#xff1a; 然后这里扫出来的结果查看的直接就是robots.txt,然后就能看到&#xff1a; …

面试题 - Vue 3 如何优化性能?

面试题 - Vue 3 如何优化性能&#xff1f; 最近&#xff0c;总有小伙伴来问我&#xff0c;在面试时应该如何回答关于优化方面的问题。其实&#xff0c;我们在日常的项目开发中&#xff0c;或多或少都接触过一些优化技巧&#xff0c;只是有时候自己没有特别留意&#xff0c;或者…

AI写代码工具ScriptEcho:赋能数据分析,驱动精准营销

在数字化时代&#xff0c;数据已成为企业发展的核心资产。而前端开发作为连接用户和数据的桥梁&#xff0c;其效率直接影响着数据分析的质量和营销决策的精准性。传统前端开发在处理海量用户行为数据时&#xff0c;常常面临效率低下、代码维护困难等挑战。然而&#xff0c;随着…

TensorFlow Lite 详解:原理、优化及基于树莓派的实战

&#x1f4cc; 1. 引言 在 AI 领域&#xff0c;深度学习模型的部署一直是一个重要课题。对于资源受限的嵌入式设备&#xff0c;如 树莓派、ARM 处理器设备、移动端 SoC&#xff0c;直接运行标准的 TensorFlow 可能会面临 计算能力不足、存储空间受限、功耗较高 等问题。 Tenso…