当前位置: 首页 > news >正文

数据库编程 SQLITE3 Linux环境

永久存储程序数据有两种方式:

  1. 用文件存储
  2. 用数据库存储

对于多条记录的存储而言,采用文件时,插入、删除、查找的效率都会很差,为了提高这些操作的效率,有计算机科学家设计出了数据库存储方式


一、数据库

数据库的基本组成:

用来管理数据库的软件被称数据库管理系统

一个数据库管理系统管理着多个数据库

一个数据库中可以包含很多张

一张表中拥有很多记录(行)

一条记录拥有很多字段(列)

每条记录的每个字段存放不同类型的数据

因此,数据库本质上是表的集合


数据库按数据的组织形式分为:

  1. 关系型数据库 ----- 本章内容
  2. 非关系型数据库

数据库管理系统软件按是否支持远程分为:

  1. 网络版 ---- MySql Oracle SQlServer
  2. 单机版 ---- sqlite

网络版的数据管理系统的整体框架:

数据库管理系统发展初期,各家开发此类软件的公司采用的通信协议是不同的,这给应用客户端开发造成很大的麻烦

因此,经过一段时间的发展,全球几家著名的数据库管理系统开发公司制定了统一的通信协议,这个统一的通信协议被称为SQL(Structure Query Language)

随着关系型数据库的不断发展,SQL成为所有数据库管理系统的统一协议

每个数据库管理系统都会提供一个命令行界面的简易客户端,应用程序员可以使用这个简易客户端学习、练习SQL语句以及辅助开发

每一条SQL语句就是一个操作请求


二、SQLite

一个单机版的数据库管理系统

所有操作请求也遵循SQL标准

开源、精悍

SQLite安装:

1.安装SQLite3
命令行下输入:sudo apt-get install sqlite32.安装SQLite3编译需要的工具包
命令行下输入: sudo apt-get install libsqlite3-dev如出现问题尝试:
sudo dpkg --purge --force-depends libsqlite3-0
sudo apt-get install libsqlite3-0
sudo apt-get install -f
sudo apt-get install libsqlite3-dev
sudo apt-get install sqlite3

支持三种字段数据类型:

INTEGER 或 INT 值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。
REAL 值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。
TEXT 值是一个文本字符串,单引号或双引号括起的字符串

使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储


三、sqlite3简易客户端的使用

1. 运行

Linux>sqlite3 ------ 只是进入sqlite3的命令行界面,不创建打开任何数据库

Linux>sqlite3 路径/数据库文件名 ----- 先创建打开指定的数据库,然后进入sqlite3的命令行界面

sqlite3管理的一个数据库,在Linux系统下用一个文件表示它,习惯上将这个文件命名为 xxx.db

2. 两种命令

  1.  . 开头的命令:简易客户端的内部命令
  2.  以 结尾的命令:前的内容为SQL语句,是简易客户端要求的结尾符

3. 常用内部命令

创建打开一个指定的数据库
sqlite> .open  路径/xxx.db 
sqlite> .help查看正在使用的数据库
sqlite> .databasesSQL语句操作结果按列对齐  ----- 重要
sqlite> .mode column 显示某表时是否显示表头 ----- 重要
sqlite> .headers on/off显示数据中的表 ------ 重要
sqlite> .tables退出sqlite命令行 ---- 重要
sqlite> .quit


四、常用SQL语句

SQL语句组成:关键字 + 运算符 + 字段名或表名 + 常量

SQL语句的关键字可以全大写、也全小写、甚至可以大小混合,一般建议采用全大写

字段名或表名的大小是区分的,aaa、Aaa、AAA认为是不同的字段名或表名,自建表建议字段名或表名全小写

1. 建表
CREATE TABLE [IF NOT EXISTS] table_name(column_name1 datatype[(size)]  [PRIMARY KEY] [AUTOINCREMENT] [NOT NULL],column_name2 datatype,column_name3 datatype,.....column_nameN datatype,
);
[]:表示可选,选用时不带[]
[AUTOINCREMENT]:只能用于INTEGER 表示如果插入新记录时没有指定该字段的值,则其值为前一条记录同字段值+1
[PRIMARY KEY]:主键,唯一标识表中的记录  主键:表中每条记录的该字段值不会重复,也即该字段值可以唯一标识一条记录
[IF NOT EXISTS]:如果表不存在则建表,如果存在则什么都不做
[NOT NULL]:表示字段内容不能为空示例:
sqlite>  CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,...>  name TEXT,sex TEXT(1),score REAL); 2. 删表
DROP TABLE 表名;示例:
sqlite> CREATE TABLE ttt(xxx TEXT,yyy TEXT);
sqlite> DROP TABLE ttt;3. 插入新记录
通用:
INSERT INTO table_name(column1, column2,...columnN)  VALUES(value1, value2,...valueN);不缺字段时:
INSERT INTO table_name  VALUES(value1,value2,...valueN); 4. 查询记录
SELECT column1, column2, columnN FROM table_name [WHERE condition];
SELECT * FROM table_name [WHERE condition];
*表示查询结果显示所有字段
无WHERE子句则查询所有记录5. where子句
所谓子句就是不能成为独立的SQL语句,只能成为一条SQL语句的一部分WHERE子句用来为一些操作指定条件
WHERE conditioncondition可以是单个条件或由AND、OR连接的多个条件比较运算符支持:
=   !=   >   <    >=    <=  用法:字段名 运算符 值IN()用法:字段名 IN(值1,值2,...,值n)   表示字段值为值1或值2或....NOT IN()用法:字段名 NOT IN(值1,值2,...,值n)  表示字段值不为值1也不为值2也不为....LIKE用法:字段名 LIKE 模式字串    模式字串中可以用%号表示任意多个字符,用_表示单个字符,默认不区分大小写GLOB用法:字段名 GLOB 模式字串    模式字串中可以用*号表示任意多个字符,用?表示单个字符,区分大小写IS NOT NULL用法:字段名 IS NOT NULL  判断字段值是否为空IS NULL用法:字段名 IS NULL  判断字段值是否为空BETWEEN AND用法:字段名 BETWEEN 值1 AND 值2   字段值>=值1 且 字段值<=值2NOT反条件用法:字段名 NOT  其它条件6. 修改记录
UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];
无WHERE子句则对所有记录进行修改7. 删除记录
DELETE FROM table_name WHERE [condition];
无WHERE子句则删除所有记录8. Sort子句
ORDER BY 字段名 ASC 或 DESC
ASC升序
DESC降序9. SQL语句中的函数
datetime('now','localtime') ---- 产生当前日期时间的字符串使用示例:
INSERT INTO Table_name VALUES(datetime('now','localtime'));count(*) 对查询结果求记录数
使用示例:
SELECT count(*) FROM student;


五、sqlite3函数库

SQL按执行完毕后是否有记录结果分为两种:

  1. 一种SQL语句的执行只论是否成功。例如:建表、删表、插入记录、修改记录、删除记录
  1. 另一种SQL语句执行完毕产生多条记录结果。例如:查询

sqlite3_open参照图:

sqlite3_exec及其回调函数的参考图:

sqlite3_get_table函数参考图1:

//头文件包含
#include <sqlite3.h>/*链接选项-lsqlite3
*///1、打开/创建一个数据库
int sqlite3_open(const char *filename,  sqlite3 **ppDb );
/*
功能:打开指定的数据库,如果数据库并存在则创建并打开指定的数据库,并创建一个后续操作该数据库的引擎
参数:filename:带路径的数据库文件名ppdb:指向sqlite句柄的指针,调用前定义一个sqlite3 *指针变量,取该指针变量的地址
返回:成功  SQLITE_OK (值为0),否则返回其他值。
*///2、如果打开数据库失败,open函数只是返回错误码,如果想要错误原因的字符串描述则调用该函数
const  char  *sqlite3_errmsg(sqlite3 *db);
/*  返回值:返回错误信息
*///3、回调函数执行sql语句
//更加适用于sql语句执行没有记录结果的情况(此时第3、4参数填NULL)或对需要依次对每条操作结果记录进行处理的情况
int sqlite3_exec(sqlite3* pDB, const char *sql, sqlite_callback callback, void*para, char** errMsg);/*
功能:执行SQL语句,查询的结果返回给回调函数callback,多个结果的操作,每个结果都会调用一次callback
参数:pDB:数据库引擎的句柄。sql:待执行的SQL 语句字符串,以’\0’结尾,不以';'结尾。callback:回调函数,用来处理查询结果,如果不需要回调(比如做insert 或者delete 操作时),可以置NULL。para:要传入回调函数的指针参数,没有可以置为NULL。errMsg:一级指向空间存放着一个char *类型的元素,该元素指向空间(二级指向空间)存放着一个字符串,该字符串内容描述出错原因,因此:1. 调用前定义一个char *类型的指针变量,传该指针变量的地址给该形参。2. 由于其二级指向空间是动态分配的,因此使用完后需要调用sqlite3_free函数进行释放;
返回值:执行成功返回SQLITE_OK,否则返回其他值
*///4、回调函数
typedef int (*sqlite_callback)(void* para,  int columnCount,  char** columnValue,char** columnName);
/*
功能:由用户处理查询的结果,每找到一条记录自动执行一次回调函数
参数:para:从sqlite3_exec()传入的参数指针;columnCount:查询到的这一条记录有多少个字段(即这条记录有多少列);columnValue:查询出来的数据都保存在这里,它实际上是个1 维数组(不要以为是2 维数组),每一个元素都是一个char * 值,是一个字段内容(用字符串来表示,以‘\0’结尾)columnName:与columnValue 是对应的,表示这个字段的字段名称。
返回值:执行成功返回SQLITE_OK,否则返回其他值
*///5、关闭
int sqlite3_close(sqlite3 *ppDb);
/*
功能:关闭sqlite数据库。
参数:ppdb:数据库句柄。
返回值:成功返回0,失败返回错误码
*///6、释放   
void sqlite3_free(void * errMsg );
/*
功能:释放存放错误信息的内存空间
参数:errMsg: 返回错误信息
*///7、非回调来执行sql语句
//更加适用于SQL语句执行后有一条或多条记录结果,且程序期望对所有记录结果的整体进行处理的情况
int sqlite3_get_table(sqlite3 *db,          /* An open database */const char *zSql,     /* SQL to be evaluated */char ***pazResult,    /* Results of the query */int *pnRow,           /* Number of result rows written here */int *pnColumn,        /* Number of result columns written here */char **pzErrmsg       /* Error msg written here */);/*
功能:非回调来执行sql语句
参数:db:数据库句柄zSql:要执行的SQL语句pazResult:查询结果,一维数组,定义一个char **的二级指针变量,调用函数时传该二级指针变量的地址,不使用应立即调用sqlite3_free_table(result)进行释放pnRow:查询出多少条记录(查出多少行) 不包括字段名所在行pnColumn:多少个字段(查出多少列)pzErrmsg:错误信息
返回值:执行成功返回SQLITE_OK,否则返回其他值
注:pazResult的字段值是连续的,是一维数组不是二维数组,从第0索引到第 pnColumn- 1索引都是字段名称,从第 pnColumn索引开始,后面都是字段值。
*///8、释放pazResult查询结果   
void sqlite3_free_table(char **pazResult);
/*参数:pazResult:指向空间存放着查询结果,指向空间为元素类型是char *的一维数组
*/

示例代码:

#include <stdio.h>
#include <sqlite3.h>int handle_a_record(void *para,int cols,char **ppval,char **ppname);int main(){sqlite3 *pdb = NULL;int ret = 0;ret = sqlite3_open("./test.db",&pdb); // openif(ret != SQLITE_OK){printf("sqlite3 not open,because %s\n",sqlite3_errmsg(pdb));sqlite3_close(pdb);pdb = NULL;return 1;}{char sql[80] = "";char *perr = NULL;sprintf(sql,"SELECT * FROM stu"); // write instructionret = sqlite3_exec(pdb,sql,handle_a_record,NULL,&perr); // exec()if(ret != SQLITE_OK){ // errorprintf("exec %s failed,because %s\n",sql,perr);sqlite3_free(perr); // sqlite3_free()perr = NULL;}}{char sql[80] = "";char *perr = NULL;char **ppret = NULL;int rows = 0;int cols = 0;int i = 0;int j = 0;sprintf(sql,"SELECT * FROM stu"); // write instructionret = sqlite3_get_table(pdb,sql,&ppret,&rows,&cols,&perr); // exec()if(ret != SQLITE_OK){ // errorprintf("exec %s failed,because %s\n",sql,perr);sqlite3_free(perr); // sqlite3_free()perr = NULL;}else{for(j = 0;j < cols;j++){printf("%-20s ",*(ppret + j));}printf("\n");}for(i = 1;i <= rows;i++){for(j = 0;j < cols;j++)     printf("%-20s ",*(ppret + i * cols + j));printf("\n");}sqlite3_free_table(ppret);ppret = NULL;
}sqlite3_close(pdb); // sqlite3_close()pdb = NULL;return 0;}int handle_a_record(void *para,int cols,char **ppval,char **ppname){int i = 0;for(i = 0;i < cols;i++){printf("%s | ",*(ppval + i));}printf("\n");return SQLITE_OK;
}

输出:


六、sqlite3函数库的并发模式

  1. 单线程模式 ----- 无锁模式
  2. 串行模式 ------ 默认模式,非阻塞互斥锁实现
  3. 读者写者模式 ------ 读写锁实现

配置sqlite3函数库的并发模式可以通过:1. 重新编译sqlite3函数库的源码 2.调用相关的接口函数进行配置

实际项目中大部分情况采用其默认模式


串行模式时,需要对sqlite3_exec、sqlite3_get_table函数进行如下形式的二次封装:

int my_sqlite3_exec(sqlite3* pdb, const char *sql, sqlite_callback callback, void*para, char** errmsg){int ret = 0;  do {ret = sqlite3_exec( pdb , sql, callback , para , errmsg );  if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED){usleep(30 * 1000);continue;}else{break;}} while(1);  return ret;
}int my_sqlite3_get_table(sqlite3 *db,          /* An open database */const char *zSql,     /* SQL to be evaluated */char ***pazResult,    /* Results of the query */int *pnRow,           /* Number of result rows written here */int *pnColumn,        /* Number of result columns written here */char **pzErrmsg       /* Error msg written here */){int ret = 0;do {ret = sqlite3_get_table(db,zSql,pazResult,pnRow,pnColumn,pzErrmsg);  if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED){usleep(30 * 1000);continue;}else{break;}} while(1);  return ret;
}

七、二次封装

实际项目代码中,直接调用sqlite3函数库中的函数实现相关功能,会很不方便,往往会将项目中可能用到的所有数据库操作代码单独作为一个模块,该模块又按表分为几个子模块(一般命名为xxxhelper),由这个模块及其子模块向其它项目代码提供需要的数据库操作接口。

public子模块:不隶属于任何一个helper子模块的操作函数,归于本子模块

一般项目中建议采用如下方案:

/*一、public子模块 -------- 项目名_db_public.c*/
/*1. 函数功能:创建打开数据库,然后带IF NOT EXISTS关键字去建表*/
sqlite3 *create_db_engine(const char *pdbfile)
{1. 调用sqlite3_open2. 建表13. 建表2。。。。n+1. 建表n成功返回引擎地址,失败返回NULL
}/*2. 对sqllite3_exec的二次封装 ------ 见上一节*//*3. 对sqllite3_get_table的二次封装 ------ 见上一节*//*4. destroy_db_engine*/
void destroy_db_engine(sqlite3 *pdb)
{sqlite3_close(pdb);
}/*二、对表1的各种操作函数封装  表1名helper.c*/
int insert_new_record_into_表名(sqlite3 *pdb,.........)
{组织sql语句调用my_sqlite3_exec 或 my_sqlite3_get_table函数执行sql语句。。。。。。
}......???? xxxxx(sqlite3 *pdb,.......)
{通过多次执行sql语句组合完成本函数功能
}/*三、对表2的各种操作函数封装  表2名helper.c*/。。。。。。。。。。。。。。。

相关文章:

数据库编程 SQLITE3 Linux环境

永久存储程序数据有两种方式&#xff1a; 用文件存储用数据库存储 对于多条记录的存储而言&#xff0c;采用文件时&#xff0c;插入、删除、查找的效率都会很差&#xff0c;为了提高这些操作的效率&#xff0c;有计算机科学家设计出了数据库存储方式 一、数据库 数据库的基本…...

独孤思维:总有一双眼睛默默观察你做副业

01 独孤昨天在陪伴群&#xff0c;分享了近期小白做副业的一些困扰。 并且以自己经历作为案例&#xff0c;分享了一些经验和方法。 最后顺势推出xx博主的关于365条赚钱信息小报童专栏。 订阅后&#xff0c;可以开拓副业赚钱思路&#xff0c;避免走一些弯路。 甚至于&#x…...

医院信息化与智能化系统(10)

医院信息化与智能化系统(10) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…...

基于YOLO11/v10/v8/v5深度学习的危险驾驶行为检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…...

Flink CDC系列之:学习理解核心概念——Transform

Flink CDC系列之&#xff1a;学习理解核心概念——Transform Transform参数元数据字段函数比较函数逻辑函数字符串函数时间函数条件函数 示例添加计算列参考元数据列使用通配符投影所有字段添加过滤规则重新分配主键重新分配分区键指定表创建配置分类映射用户定义函数已知限制 …...

MyBatis-Plus:简化 CRUD 操作的艺术

一、关于MyBatis-Plus 1.1 简介 MyBatis-Plus 是一个基于 MyBatis 的增强工具&#xff0c;它旨在简化 MyBatis 的使用&#xff0c;提高开发效率。 ​ ‍ ‍ ‍ ​ ‍ 关于Mybatis 简介 MyBatis 是一款流行的 Java 持久层框架&#xff0c;旨在简化 Java 应用程序与数…...

Windows on ARM编译安装openBLAS

Windows on ARM编译安装openBLAS 要求下载源码OpenBLAS可以使用LLVM工具链(clang-cl和flang)从源代码为Windows on ARM(WoA)进行构建。v0.3.24版本(预构建包)的构建和测试已通过。 要求 LLVM:版本需大于等于17.0.4 LLVM版本16及以下会生成冲突的符号(如_QQ*等)。 LL…...

FPGA编程语言VHDL与Verilog的比较分析!!!

VHDL&#xff08;VHSIC硬件描述语言&#xff09;和Verilog都是用于硬件描述和FPGA编程的工业标准语言。它们在语法和设计理念上存在一些差异&#xff0c;以下是两者的比较分析&#xff1a; 1. 历史背景 VHDL&#xff1a; 开发于1980年代初期&#xff0c;最初用于美国国防部的…...

C语言——八股文(笔试面试题)

1、 什么是数组指针&#xff0c;什么是指针数组&#xff1f; 数组指针&#xff1a;指向数组的指针 指针数组&#xff1a;数组中的元素都是指针 2、 什么是位段&#xff0c;什么是联合体 位段&#xff08;Bit Field&#xff09;&#xff1a;在C语言中&#xff0c;允许在一个整数…...

解决 Oracle 数据库错误 ORA-12516:监听器无法找到匹配协议栈的处理程序

在使用 Oracle 数据库时&#xff0c;有时会遇到错误 ORA-12516&#xff0c;这个错误表明 Oracle 数据库的监听器无法为新的连接请求找到一个可用的处理程序&#xff0c;这通常是因为达到了连接数上限、配置问题或资源限制。本文将详细介绍如何解决这个问题。 一、错误描述 当…...

Flarum:简洁而强大的开源论坛软件

Flarum简介 Flarum是一款开源论坛软件&#xff0c;以其简洁、快速和易用性而闻名。它继承了esoTalk和FluxBB的优良传统&#xff0c;旨在提供一个不复杂、不臃肿的论坛体验。Flarum的核心优势在于&#xff1a; 快速、简单&#xff1a; Flarum使用PHP构建&#xff0c;易于部署&…...

方法+数组

1. 方法 1. 什么是方法 方法定义&#xff1a; // []表示可写可不写[public] [static] type name ( [type formal , type formal , ...]){方法体&#xff1b;[return value ;] }[修饰符] 返回值类型 方法名称([参数类型 形参 , 参数类型 形参 ...]){方法体代码;[return 返回值…...

驱动-----adc

在key1.c的基础上进行对adc1.c进行编写 首先将文件里面的key全部改为adc 再修改一下设备号 按键和adc的区别是什么,按键只需要按一下就触发了,并且不需要返回一个值出来, adc要初始化,启动,返回值 以下是裸机adc的代码: #include <s3c2440.h> #include "ad…...

js实现点击图片,使图片跟随鼠标移动(把注释打开是图片随机位置)

代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title>&l…...

MacOS的powermetrics命令查看macbook笔记本的耗能情况,附带查看ANE的工作情况

什么是 powermetrics&#xff1f; powermetrics 是 macOS 系统自带的一个命令行工具&#xff0c;用于收集和分析系统能源消耗数据。通过它&#xff0c;我们可以深入了解 Mac 的硬件性能、软件行为以及能源使用情况&#xff0c;从而优化系统配置&#xff0c;提高电池续航时间。…...

字符串函数

大家好&#xff0c;今天我们来了解几个字符串函数 1.strcpy函数 这个函数是一个字符串复制函数&#xff0c;其全称为string copy&#xff0c;它可以将一个源字符数组的内容复制到目标字符数组中&#xff0c;我们需要关注几个问题&#xff0c;首先源字符串必须以&#xff3c;0…...

Java数组的地址和元素访问 C语言空指针与野指针

1. public static void main(String[] args) {int []arr{1,2,3,4,5};int numarr[0];System.out.println(num);System.out.println(arr[1]);System.out.println(arr);//[I610f87f48//[表示地址 I表示数据类型 表示间隔符号&#xff08;固定格式&#xff09;//10f87f48表示地址…...

如何在Linux系统中使用SSH进行安全连接

如何在Linux系统中使用SSH进行安全连接 SSH简介 安装SSH 在Debian/Ubuntu系统中安装 在CentOS/RHEL系统中安装 启动SSH服务 验证SSH是否安装成功 SSH配置 配置监听端口 配置登录方式 SSH客户端 安装SSH客户端 使用SSH客户端 SSH密钥认证 生成SSH密钥对 复制公钥到远程服务器…...

Pandas 数据可视化指南:从散点图到面积图的全面展示

Pandas 数据可视化指南&#xff1a;从散点图到面积图的全面展示 本文介绍了使用 Pandas 进行数据可视化的多种方法&#xff0c;包括散点图、折线图、条形图、直方图、饼图和面积图等&#xff0c;涵盖了常见的图表类型及其实现方式。通过提供详细的代码示例&#xff0c;展示了如…...

Flink + Kafka 实现通用流式数据处理详解

Flink Kafka 实现通用流式数据处理详解 在大数据时代&#xff0c;实时数据处理和分析成为企业快速响应市场变化、提高业务效率和优化决策的关键技术。Apache Flink和Apache Kafka作为两个重要的开源项目&#xff0c;在数据流处理领域具有广泛的应用。本文将深入探讨Flink和Ka…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...