【网络编程 + 数据库】select 与 epoll 核心区别详解 + SQLite 入门到 C 接口全攻略

本篇为当日学习整理笔记,系统梳理IO 多路复用中 select 与 epoll 的核心差异 ,以及SQLite 轻量数据库的基础语法、常用命令与 C 语言接口。内容从基础概念到实操语法,再到编程接口,适合嵌入式 / 网络编程入门学习者复习参考。

文章目录

  • [一、IO 多路复用:select 与 epoll 核心区别](#一、IO 多路复用:select 与 epoll 核心区别)
    • [1.1 核心区别总览表](#1.1 核心区别总览表)
    • [1.2 select 核心特点](#1.2 select 核心特点)
    • [1.3 epoll 核心特点](#1.3 epoll 核心特点)
  • [二、SQLite 数据库基础](#二、SQLite 数据库基础)
    • [2.1 数据库的概念与分类](#2.1 数据库的概念与分类)
    • [2.2 SQLite 安装](#2.2 SQLite 安装)
    • [2.3 SQLite 常用元命令](#2.3 SQLite 常用元命令)
  • [三、SQL 基础语法全梳理](#三、SQL 基础语法全梳理)
    • [3.1 SQLite 支持的数据类型](#3.1 SQLite 支持的数据类型)
    • [3.2 表的创建与删除](#3.2 表的创建与删除)
    • [3.3 数据操作:增删改查](#3.3 数据操作:增删改查)
    • [3.4 条件查询与排序](#3.4 条件查询与排序)
    • [3.5 多表联合查询](#3.5 多表联合查询)
  • [四、SQLite C 语言接口详解](#四、SQLite C 语言接口详解)
    • [4.1 sqlite3_open:打开数据库](#4.1 sqlite3_open:打开数据库)
    • [4.2 sqlite3_exec:执行 SQL 语句](#4.2 sqlite3_exec:执行 SQL 语句)
    • [4.3 sqlite3_close:关闭数据库](#4.3 sqlite3_close:关闭数据库)
  • 五、学习总结

一、IO 多路复用:select 与 epoll 核心区别

IO 多路复用是网络编程中处理高并发连接的核心技术,select 和 epoll 是 Linux 下最经典的两种实现,二者在设计思路、性能、触发模式上有本质区别。

1.1 核心区别总览表

对比维度 select epoll
监听集合本质 数组结构,有数量上限(默认 1024) 内核事件表,无数量上限
数据拷贝开销 每次调用都需在用户态与内核态间全量拷贝集合,开销大 事件表常驻内核,仅返回就绪事件,无需全量拷贝,开销小
触发模式 仅支持水平触发(低速模式) 支持水平触发(默认)和边沿触发(高速模式)
事件定位方式 需手动遍历整个集合查找就绪文件描述符 自动返回就绪 fd 列表,无需遍历

1.2 select 核心特点

  1. 文件描述符集合有上限 select 本质上通过fd_set数组管理待监听的文件描述符,受系统常量FD_SETSIZE限制,Linux 默认最大监听 1024 个文件描述符,不适合超大并发场景。
  2. 用户态与内核态拷贝开销大 select 的监听集合维护在应用层(用户态),每次调用都需要把整个集合从用户态拷贝到内核态,内核检测完事件后再拷贝回用户态。连接数越多,拷贝开销呈线性增长。
  3. 仅支持水平触发模式 水平触发也叫低速模式:只要文件描述符上还有未处理的数据,每次调用 select 都会重复通知该事件。优点是编程简单、不易丢数据,缺点是触发效率低。
  4. 需要手动遍历查找就绪 fd select 返回后只会告知 "有事件就绪",不会指明具体是哪个 fd,应用程序需要遍历整个监听集合逐个检查,连接数越多效率越低。

1.3 epoll 核心特点

  1. 监听事件无数量上限 epoll 在内核中通过红黑树管理待监听的文件描述符,没有数量上限,理论上只受限于系统内存,适合高并发大连接场景。
  2. 内核级管理,拷贝开销极低 epoll 的事件表直接常驻内核空间,应用程序仅在添加 / 删除 fd 时做一次拷贝,监听过程中无需重复拷贝整个集合。内核检测到就绪事件后,通过就绪链表直接返回事件,极大降低了资源开销。
  3. 双触发模式可选
    • 水平触发(默认):和 select 逻辑一致,有未处理数据就持续通知,编程简单。
    • 边沿触发:仅在数据到来的瞬间通知一次,是高速模式。处理效率更高,但要求程序一次性读完缓冲区数据,编程复杂度更高,处理不当容易丢数据。
  4. 自动返回就绪 fd epoll 返回时直接将就绪的文件描述符列表返回给应用层,程序不需要遍历整个集合,直接处理就绪事件即可,连接数越多效率优势越明显。

二、SQLite 数据库基础

2.1 数据库的概念与分类

数据库是能够对大批量数据进行高效增、删、改、查管理的软件,按照数据存储方式主要分为两大类:

(1)关系型数据库
  • 数据以表格形式存储在磁盘文件中,支持标准 SQL 语言操作
  • 代表产品:Oracle、MySQL、SQLite
  • 特点:数据结构严谨、支持事务、适合持久化存储
(2)非关系型数据库
  • 多为内存数据库,数据存储在内存中,读写速度极快
  • 代表产品:Redis、各类 NoSQL 数据库
  • 特点:读写速度快、结构灵活、适合高并发缓存场景

2.2 SQLite 安装

SQLite 是一款轻量级嵌入式数据库,无需独立服务进程,以单个文件形式存在,Linux 下安装命令:

复制代码
sudo apt-get install sqlite3

2.3 SQLite 常用元命令

注意:这类.开头的命令是 sqlite3 终端工具的内置命令,不是标准 SQL 语句,不需要加分号。

命令 功能
.tables 查看当前数据库中所有表名
.databases 列出当前附加的数据库名称与文件路径
.headers on/off 开启 / 关闭查询结果的列名显示
.mode 模式 设置数据显示格式(如 column、list 等)
.schema 表名 查看指定表的建表语句
.width 数值 设置每列的显示宽度

三、SQL 基础语法全梳理

SQL 是操作关系型数据库的标准语言,SQLite 支持标准 SQL 的核心子集。

3.1 SQLite 支持的数据类型

类型 说明
INTEGER 整数类型
REAL 浮点数类型
TEXT 文本字符串类型
BLOB 二进制数据类型

3.2 表的创建与删除

(1)创建表

语法:

复制代码
create table 表名 (
    列名称1 数据类型1,
    列名称2 数据类型2,
    ...
);

示例:

复制代码
create table student (
    id integer,
    name text,
    sex text,
    age integer,
    score integer
);
(2)删除表

语法:

复制代码
drop table 表名称;

示例:

复制代码
drop table student;

3.3 数据操作:增删改查

(1)插入数据 insert

语法:

复制代码
-- 全列插入
insert into 表名 values (值1, 值2, ...);
-- 指定列插入
insert into 表名 (列1, 列2) values (值1, 值2);

示例:

复制代码
-- 全列插入
insert into student values (1, "张三", "男", 18, 90);
-- 允许部分字段为NULL
insert into student values (3, "王二", NULL, NULL, NULL);
-- 指定列插入
insert into student (id, name, sex) values (4, "赵五", "男");
(2)查询数据 select

语法:

复制代码
select 列名称1, 列名称2 from 表名;
-- 查询所有列
select * from 表名;

示例:

复制代码
select * from student;
select name,score from student;
(3)更新数据 update

语法:

复制代码
update 表名称 set 列名称 = 新值 where 匹配条件;

示例:

复制代码
update student set score=91 where name="赵五";
(4)删除数据 delete

语法:

复制代码
delete from 表名称 where 列名称 = 值;

示例:

复制代码
delete from student where name = "王二";

3.4 条件查询与排序

(1)where 条件子句

用于筛选符合条件的数据,常用运算符:

运算符 含义
= 等于
<> 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
BETWEEN ... AND ... 在某个范围内
LIKE 模糊匹配,%代表任意字符

示例:

复制代码
-- 模糊查询姓赵的学生
select name,score from student where name like "赵%";
-- 查询成绩大于等于90分的学生
select name from student where score >= 90;
-- 多条件组合
select name,score from student where name like "赵%" and score > 95;
(2)排序 order by

语法:

  • asc:升序(默认)
  • desc:降序

示例:

复制代码
-- 男生按成绩降序排列
select name,score from student where sex="男" order by score desc;

3.5 多表联合查询

(1)cross join 交叉连接

返回两张表的笛卡尔积,即所有行的组合。 示例:

复制代码
select 学生信息.姓名 as 姓名, 课程信息.名称 as 课程, 课程信息.学分 as 学分 
from 学生信息 cross join 课程信息;
(2)inner join 内连接

只返回两张表中匹配条件的行,是最常用的连接方式。 示例:

复制代码
-- 两表连接
select 学生信息.姓名 as 姓名, 成绩信息.成绩 as 成绩 
from 学生信息 inner join 成绩信息 
on 学生信息.ID = 成绩信息.学生ID;
-- 三表连接
select 学生信息.姓名 as 姓名, 课程信息.名称 as 课程, 成绩信息.成绩 as 成绩
from 学生信息 inner join 成绩信息 on 学生信息.ID = 成绩信息.学生ID
inner join 课程信息 on 成绩信息.课程ID = 课程信息.ID;
(3)left outer join 左外连接

以左表为准,右表没有匹配数据时返回 NULL。 示例:

复制代码
select 学生信息.姓名 as 姓名,成绩信息.成绩 as 成绩 
from 学生信息 left outer join 成绩信息 
on 学生信息.ID = 成绩信息.学生ID;

四、SQLite C 语言接口详解

SQLite 提供了一套 C 语言函数接口,可在代码中直接操作数据库,核心有 3 个函数。

4.1 sqlite3_open:打开数据库

函数原型:

复制代码
int sqlite3_open(
    const char *filename,   /* 数据库文件名(UTF-8编码) */
    sqlite3 **ppDb          /* 输出参数:数据库句柄 */
);
  • 功能:打开一个数据库文件,如果文件不存在则自动创建。
  • 参数 :
    • filename:数据库文件路径
    • ppDb:二级指针,用来返回数据库句柄,后续所有操作都通过该句柄完成
  • 返回值 :成功返回SQLITE_OK,失败返回对应错误码。

4.2 sqlite3_exec:执行 SQL 语句

函数原型:

复制代码
int sqlite3_exec(
    sqlite3*,                  /* 已打开的数据库句柄 */
    const char *sql,           /* 要执行的SQL语句 */
    int (*callback)(void*,int,char**,char**),  /* 回调函数 */
    void*,                     /* 传给回调函数的参数 */
    char **errmsg              /* 输出参数:错误信息 */
);
  • 功能:执行一条标准 SQL 语句,是最核心的执行接口。
  • 参数说明 :
    1. 已打开的数据库句柄
    2. sql:要执行的 SQL 字符串
    3. callback:回调函数,仅执行 select 查询时使用 。每查到一行数据就会调用一次该函数,用于处理查询结果;增、删、改操作不需要回调,传NULL即可。
    4. 传给回调函数的第一个参数,可用来在主函数和回调之间传递数据
    5. errmsg:二级指针,执行失败时会指向错误描述字符串,使用完需要调用sqlite3_free()释放
  • 返回值 :成功返回SQLITE_OK,失败返回错误码。

回调函数说明: 原型:int callback(void *arg, int colnum, char **pcontent, char **ptitle)

  • arg:主函数传入的自定义参数
  • colnum:查询结果的列数
  • pcontent:字符串数组,存储每一列的内容
  • ptitle:字符串数组,存储每一列的列名 返回值必须为 0,否则会中断查询。

4.3 sqlite3_close:关闭数据库

函数原型:

复制代码
int sqlite3_close(sqlite3*);
  • 功能:关闭数据库连接,释放相关资源。
  • 注意:程序结束前必须调用该函数,否则可能造成资源泄漏和数据损坏。

五、学习总结

  1. select 与 epoll 的核心差异在于事件管理的位置、拷贝开销、触发模式和事件定位方式,epoll 在高并发场景下性能远优于 select。
  2. SQLite 是轻量嵌入式关系型数据库,支持标准 SQL 语法,通过单个文件存储数据,适合嵌入式和小型项目。
  3. SQL 语法核心围绕增删改查,条件筛选、排序、多表连接是查询的核心技能。
  4. SQLite 的 C 接口简洁易用,sqlite3_open/sqlite3_exec/sqlite3_close三个函数即可完成绝大多数数据库操作,查询操作通过回调函数获取结果。
相关推荐
一隅论数智3 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
未济3 天前
linux 配置环境变量
linux
傲世仙尊3 天前
目录即文件-Ext文件系统收尾篇
linux·c语言
XiHongShi20163 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
爱吃苹果的日记本3 天前
离散数学第六课
学习·离散数学
这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能