数据库 --- SQLite/命令/select等增删改查语句/数据库编程 --- Linux

1、数据库

高效对大批量数据进行存储、管理、查询和维护的软件系统(核心是 "数据管理")

1.1 分类

  • 关系型数据库(基于二维表结构,支持 SQL)
    • Oracle(企业级商用)
    • Mysql(开源主流)
    • SQLServer(微软商用)
    • SQLite(轻量级嵌入式)
  • 非关系型数据库(NoSQL)不是传统表格模型的数据库
    • Redis(键值对型)

1.2 SQLite数据库

  • 轻量级嵌入式关系型数据库,无需独立服务进程
  • 支持标准SQL编程语言,跨平台,单文件存储数据库
  • 所有数据库支持:SQL编程语言

1.3 SQLite数据库的安装

  • 虚拟机网络连通
  • apt-get工具集配置成功
  • 安装SQlite软件
bash 复制代码
# 安装sqlite3核心工具
sudo apt-get install sqlite3
# 安装sqlite3开发库(C/C++编程用)
sudo apt-get install libsqlite3-dev
# 安装可视化管理工具
sudo apt-get install sqlitebrowser

Navicat 是通用数据库可视化工具(支持 SQLite)
  • 运行sqlite3
bash 复制代码
sqlite3

.quit    //退出

//如下:
linux@spring:~$ sqlite3  # 启动sqlite3(默认内存数据库)
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .quit  # 退出(补充:.exit 也可退出)
linux@spring:~$ 

//.open test.db 可打开 / 创建名为 test.db 的本地数据库文件(持久化存储)

1.4 Sqlite 特有命令(以.开头,区分 SQL 语句)

命令 功能说明
.databases 列出附加数据库的名称和文件路径
.header(s) ON | OFF 开启 / 关闭查询结果的列名头部(ON 显示列名,OFF 不显示)
.mode MODE 设置数据显示格式,常用: - csv:逗号分隔 - column:列对齐(常用) - line:每行一个字段 - list:默认,竖线分隔 - table:表格形式(最易读)
.schema [TABLE] 显示表的创建语句(不加 TABLE 则显示所有表)
.quit / .exit 退出 sqlite3 终端
.tables 查看数据库中所有表名
.show 查看当前终端配置(如 mode、header 等)

1.5 SQL 核心语句(必须以;结尾)

1.5.1 创建表(create table)

sql 复制代码
CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
);

-- 规范:字段名建议用英文(避免中文乱码),补充注释和约束
create table student (
    id integer primary key asc,  -- 学号(主键,自增)
    name text not null,                   -- 姓名(非空)
    gender text check(gender in ('男','女')),  -- 性别(约束只能是男/女)
    age integer check(age > 0),           -- 年龄(约束大于0)
    score integer default 0               -- 成绩(默认值0)
);


--eg:
create table student (id integer primary key asc, name text, gender text,
age integer, score integer);

1.5.2 删除表(drop table)

bash 复制代码
-- 基础语法
drop table if exists student;  -- 补充if exists,避免表不存在时报错

drop table if exists student;

1.5.3 插入数据(insert into)

sql 复制代码
-- 向表格中插入新的行:
INSERT INTO 表名称 VALUES (值1, 值2,....);

insert into student values (1002, "李四", "女", 13, 80);


指定所要插入数据的列:
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

-- 全字段插入(顺序与表结构一致)
insert into student (id, name, gender, age, score) 
values (1, '张三', '男', 18, 85);

-- 省略主键(自增字段)
insert into student (name, gender, age, score) 
values ('李四', '女', 19, 90), ('王五', '男', 18, 59);  -- 批量插入

-- 插入默认值
insert into student (name, gender) values ('赵六', '男');  -- 成绩默认0

1.5.4 删除数据(delete from)

sql 复制代码
删除某行:
DELETE FROM 表名称 WHERE 列名称 = 值

删除所有行:
DELETE FROM table_name  /  DELETE * FROM table_name

-- 删除符合条件的数据(慎用无where的删除!)
delete from student where score < 60;  -- 删除不及格的学生
delete from student where id = 3;      -- 删除指定学号的学生
-- 清空表(保留表结构,自增主键重置)
delete from student;  -- 自增主键不重置

1.5.5 更新数据(update)

sql 复制代码
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值;

UPDATE Person SET FirstName = 'Fred' WHERE LastName = 'Wilson'

UPDATE Person SET Address = 'Zhongshan 23', City = 'Nanjing' WHERE LastName = 'Wilson'


-- 修改符合条件的数据
update student set score = 60 where score < 60;  -- 不及格的都改60
-- 批量修改多个字段
update student set age = 20, score = 88 where name = '张三';

1.5.6 查询数据(select)

基础语法select 字段1,字段2... from 表名 where 条件;

sql 复制代码
-- 查询所有字段
select * from student;
-- 查询指定字段
select id, score from student;
-- 带条件查询(运算符)
select name from student where score < 60 and gender = '男';  -- 原笔记引号统一为单引号
-- 模糊查询(like)
select name from student where name like '%张%';  -- 包含"张"的姓名
-- 范围查询(between)
select name from student where score between 60 and 80;  -- 60≤成绩≤80

-- 如果 column 的值等于值1、值2、值3中的任意一个,条件成立
SELECT * FROM table WHERE column IN (值1, 值2, 值3);
-- 等价于:
SELECT * FROM table 
WHERE column = 值1 OR column = 值2 OR column = 值3;

运算符补充

运算符 描述
= 等于
<> / != 不等于
> / < 大于 / 小于
>= / <= 大于等于 / 小于等于
BETWEEN ... AND ... 在范围内
LIKE 模糊匹配
IN 匹配多个值
AND / OR 多条件连接

1.5.7 排序(order by)

sql 复制代码
ORDER BY 语句用于根据指定的列对结果集进行排序


-- desc:降序(从高到低),asc:升序(默认,可省略)
select id, name from student where score > 60 order by score desc;
select id, name from student where score > 60 order by score;  -- 等价于asc
-- 多字段排序(先按成绩降序,再按年龄升序)
select id, name from student order by score desc, age asc;
-- 1. 先按 score 从高到低排序(降序)
-- 2. 当 score 相同时,再按 age 从小到大排序(升序)

1.6 SQLite 数据类型

SQLite 采用 "动态类型",常用核心类型:

因为类型是跟数据走的,不是跟列绑定的

sql 复制代码
-- 创建表时写的类型只是"建议"
CREATE TABLE student (
    id INTEGER,        -- 建议存整数
    name TEXT,         -- 建议存文本
    age INTEGER        -- 建议存整数
);

-- 但我可以"不听话"
INSERT INTO student VALUES ('abc', 123, '18');  
-- id列存了字符串,name列存了整数,age列存了字符串

-- 查看实际类型
SELECT id, typeof(id), name, typeof(name), age, typeof(age) 
FROM student;

id  | typeof(id) | name | typeof(name) | age | typeof(age)
----|------------|------|--------------|-----|------------
abc | text       | 123  | integer      | 18  | text
类型 说明 对应常规类型 例子
INTEGER 整型(整数,含自增) int 42, -100, 0
REAL 浮点型(小数) float/double 3.14, 2.0e10
TEXT 文本型(字符串) varchar 'hello', "world"
BLOB 二进制型 图片 / 文件等 x'ABCDEF'
NULL 空值 NULL NULL

1.7 多表联合查询

1.7.1 交叉连接(cross join)

笛卡尔积:两表所有行两两组合(无实际业务意义,慎用)

sql 复制代码
select si.name as 姓名, c.cname as 课程 
from student_info si cross join course c;  -- 别名简化(si=student_info,c=course)

1.7.2 内连接(inner join)

只返回两表匹配的行(最常用)

sql 复制代码
select si.name as 姓名, s.score as 成绩 
from student_info si inner join score s 
on si.id = s.stu_id;  -- 连接条件:学生学号=成绩表学号

1.7.3 外连接(outer join)

  • 左外连接(left join):返回左表所有行,右表无匹配则为 NULL(常用)
  • 右外连接(right join):SQLite 不支持,可通过左连接互换表实现
sql 复制代码
select si.name as 姓名, s.score as 成绩 
from student_info si left join score s 
on si.id = s.stu_id;  -- 即使学生无成绩,也会显示姓名,成绩为NULL

1.7.4 三表联合查询

sql 复制代码
select si.name as 姓名, c.cname as 课程, s.score as 成绩
from student_info si 
left join score s on si.id = s.stu_id
left join course c on s.cid = c.cid
where s.score > 60  -- 筛选及格的成绩
order by s.score desc;

1.8 数据库编程(C 语言接口)

1.8.1 sqlite3_open

  • 函数原型:
cpp 复制代码
int sqlite3_open(
    const char *filename,  /* 数据库文件路径(UTF-8):":memory:"=内存数据库,"test.db"=本地文件 */
    sqlite3 **ppDb         /* 输出参数:数据库句柄的指针 */
);
  • 功能:打开 / 创建数据库,获取操作数据库的句柄
  • 返回值:
    • 成功:SQLITE_OK(宏定义,值为 0)
    • 失败:错误码(如SQLITE_CANTOPEN),可通过sqlite3_errmsg获取对应的英文错误描述

1.8.2 sqlite3_errmsg

  • 函数原型:
cpp 复制代码
const char *sqlite3_errmsg(sqlite3* db);
  • 功能:传入数据库句柄,返回当前错误的英文描述字符串
  • 示例:fprintf(stderr, "fail to sqlite3_exec:%s\n", perrmsg);

1.8.3 sqlite3_exec

  • 函数原型:
cpp 复制代码
int sqlite3_exec(
    sqlite3* db,                          /* 已打开的数据库句柄 */
    const char *sql,                      /* 要执行的SQL语句(以;结尾) */
    int (*callback)(void*,int,char**,char**),  /* 回调函数(仅select需要) */
    void *arg,                            /* 传给回调函数的自定义参数 */
    char **errmsg                         /* 输出参数:错误信息(需用sqlite3_free释放) */
);
  • 功能:执行任意 SQL 语句(增删改查)
  • 回调函数说明(select时处理查询结果):
cpp 复制代码
// 参数:arg=自定义参数,col_num=select命令生成新表的列数,col_values=所有列数据字符串的指针数组名,col_names=所有列名称字符串的指针数组名
int callback(void *arg, int col_num, char **col_values, char **col_names) {
    for (int i=0; i<col_num; i++) {
        printf("%s = %s\n", col_names[i], col_values[i] ? col_values[i] : "NULL");
    }
    return 0;  // 返回0继续处理下一行,非0终止查询
}
  • 返回值:成功返回SQLITE_OK,失败返回错误码

1.8.4 sqlite3_close

  • 函数原型:
cpp 复制代码
int sqlite3_close(sqlite3* db);
  • 功能:关闭数据库句柄,释放资源
  • 注意:需确保所有 SQL 操作完成后调用,否则返回SQLITE_BUSY

1.8.5 sqlite3_free

  • 函数原型:
cpp 复制代码
void sqlite3_free(void* ptr);
  • 功能:释放 sqlite3 分配的内存(如sqlite3_exec的 errmsg 参数)
  • 示例:sqlite3_free(errmsg);

1.8.6 示例

cpp 复制代码
#include <stdio.h>
#include <sqlite3.h>

// 回调函数:处理select查询结果
int select_callback(void *arg, int col_num, char **col_values, char **col_names) {
    printf("--- %s ---\n", (char*)arg);
    for (int i=0; i<col_num; i++) {
        printf("%-8s: %s\n", col_names[i], col_values[i] ? col_values[i] : "NULL");
    }
    return 0;
}

int main() {
    sqlite3 *db = NULL;
    char *errmsg = NULL;
    int ret;

    // 1. 打开数据库
    ret = sqlite3_open("test.db", &db);
    if (ret != SQLITE_OK) {
        printf("打开数据库失败:%s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return -1;
    }

    // 2. 创建表
    char *create_sql = "create table if not exists student (id integer primary key autoincrement, name text, score integer);";
    ret = sqlite3_exec(db, create_sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK) {
        printf("创建表失败:%s\n", errmsg);
        sqlite3_free(errmsg);
        sqlite3_close(db);
        return -1;
    }

    // 3. 插入数据
    char *insert_sql = "insert into student (name, score) values ('张三', 85), ('李四', 90);";
    ret = sqlite3_exec(db, insert_sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK) {
        printf("插入数据失败:%s\n", errmsg);
        sqlite3_free(errmsg);
        sqlite3_close(db);
        return -1;
    }

    // 4. 查询数据
    char *select_sql = "select * from student;";
    ret = sqlite3_exec(db, select_sql, select_callback, (void*)"学生信息", &errmsg);
    if (ret != SQLITE_OK) {
        printf("查询数据失败:%s\n", errmsg);
        sqlite3_free(errmsg);
        sqlite3_close(db);
        return -1;
    }

    // 5. 关闭数据库
    sqlite3_close(db);
    return 0;
}
相关推荐
圥忈&&丅佽&&扗虖2 小时前
修改ubuntu IP
linux·ubuntu
大母猴啃编程2 小时前
MySQL内外连接
数据库·sql·mysql
橘颂TA2 小时前
【MySQL】视图
数据库·mysql
何中应2 小时前
ubuntu如何设置远程工具连接
linux·运维·ubuntu
黑蛋同志2 小时前
Rocky Linux 10 上搭建 社区版 GitLab CE
linux·运维·gitlab
Hello World . .2 小时前
数据库编程
数据库
吾诺2 小时前
【MySQL 的数据目录】
数据库·mysql·adb
程序猿编码2 小时前
深入解析:一款能识别TLS流量特征的Linux内核连接跟踪模块
linux·网络·安全·内核模块·tls
fygfh.2 小时前
Linux外设之 串口(UART)的使用
linux·运维·单片机