Linux下数据库相关知识点及SQLite3相关知识,和callback回调函数
一、Linux下数据库相关知识点
1. 常见数据库管理系统 (DBMS)
- 关系型数据库:
- MySQL/MariaDB:广泛使用的开源关系型数据库,支持复杂查询、事务、存储过程等。
- PostgreSQL:功能强大的开源关系型数据库,支持复杂数据类型和高级查询功能。
- SQLite:轻量级、嵌入式的关系型数据库,常用于本地存储,如移动应用、桌面应用等。
- Oracle Database:商业关系型数据库,支持复杂的企业级应用。
- 非关系型数据库 (NoSQL):
- MongoD:基于文档的NoSQL数据库,使用JSON格式存储数据。
- Redis:键值对存储系统,支持丰富的数据结构,常用于缓存、消息队列等场景。
- Cassandra:分布式NoSQL数据库,适合处理大量的数据和高可用性要求。
2. 数据库的基本概念
- 数据库 (Database):存储结构化数据的容器,包含多个表。
- 表 (Table):数据库中的一个二维数据结构,由行(记录)和列(字段)组成。
- 字段 (Field):表中的一个数据列,定义了数据的类型和名称。
- 记录 (Record):表中的一行数据,每一行代表一个完整的数据实体。
- 主键 (Primary Key):唯一标识表中每条记录的字段或字段组合。
- 外键 (Foreign Key):表中的一个字段或字段组合,用于建立与另一个表的关系。
- 索引 (Index):用于加速数据检索的数据库结构。
- 查询 (Query):从数据库中检索数据的操作,通常使用SQL语句。
3. 数据库操作的基本命令
- 创建数据库:`CREATE DATABASE database_name;`
- 创建表:`CREATE TABLE table_name (column1 datatype, column2 datatype, ...);`
- 插入数据:`INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);`
- 查询数据:`SELECT column1, column2 FROM table_name WHERE condition;`
- 更新数据:`UPDATE table_name SET column1 = value1 WHERE condition;`
- 删除数据:`DELETE FROM table_name WHERE condition;`
- 删除表:`DROP TABLE table_name;`
4. 备份与恢复
- 备份:
- MySQL/MariaDB:`mysqldump -u username -p database_name > backup.sql`
- PostgreSQL:`pg_dump database_name > backup.sql`
- 恢复:
- MySQL/MariaDB:`mysql -u username -p database_name < backup.sql`
- PostgreSQL:`psql database_name < backup.sql`
二、SQLite3相关知识
1. SQLite3简介
- 嵌入式数据库:SQLite是一个轻量级、无服务器、嵌入式的关系型数据库管理系统,它将整个数据库存储在单个文件中,无需独立的服务器进程。
- 自包含:SQLite数据库引擎是一个库,它可以嵌入到任何应用程序中,不需要安装和配置。
- 高效且易用:SQLite非常适合嵌入式系统、移动应用和小型项目,不需要配置,开箱即用。
2. SQLite3的基本操作
- 创建数据库:SQLite数据库是一个文件,可以通过简单的命令创建:
```bash
sqlite3 database_name.db
如果 `database_name.db` 文件不存在,SQLite会自动创建它。
- 创建表:
```sql
CREATE TABLE table_name (
id INTEGER PRIMARY KEY AUTOINCREMENT,
column1 TEXT,
column2 INTEGER
);
- 插入数据:
```sql
INSERT INTO table_name (column1, column2) VALUES ('value1', 123);
- 查询数据:
```sql
SELECT column1, column2 FROM table_name WHERE condition;
- 更新数据:
```sql
UPDATE table_name SET column1 = 'new_value' WHERE condition;
- 删除数据:
```sql
DELETE FROM table_name WHERE condition;
- 关闭数据库:在SQLite命令行工具中输入 `.quit` 或 `exit` 关闭数据库连接。
3. SQLite的特殊功能
- 事务 (Transaction):SQLite支持ACID(原子性、一致性、隔离性、持久性)事务,可以通过 `BEGIN TRANSACTION`、`COMMIT` 和 `ROLLBACK` 来管理。
- 内存数据库:SQLite可以创建一个完全在内存中运行的数据库,适合临时数据存储,使用 `:memory:` 作为数据库名称。
- SQL的扩展支持:SQLite支持标准SQL的大部分功能,并提供了一些扩展,如 `AUTOINCREMENT`、 `UNIQUE` 和 `CHECK` 约束。
4. 常用SQLite命令
- 列出所有表:`.tables`
- 显示表结构:`.schema table_name`
- 导入数据:`.import file_name table_name`
- 导出数据:`.output file_name`,然后执行查询或 `.dump` 导出整个数据库
5. 安全与加密
- 加密数据库:SQLite本身不支持加密,但可以使用 `SQLCipher`(一个SQLite的扩展)来加密数据库文件,确保数据安全。
6. 性能优化
- 使用索引:通过在查询常用的列上建立索引来提高查询速度。
- 减少事务:一次提交多个插入操作,可以显著提高性能。
- 合并相似查询:通过优化SQL查询来减少数据库访问次数,减少I/O操作。
以下是一个通用的函数参数及其解释的示例。假设有一个处理SQLite数据库的函数 `insert_into_database`,它将数据插入到指定的表中。
函数定义
void insert_into_database(sqlite3 *db, const char *table_name, const char *word, const char *meaning);
参数解释
1. `sqlite3 *db`
- 类型:`sqlite3 *`
- 描述:指向SQLite数据库连接对象的指针。在调用 `sqlite3_open` 函数时,数据库连接对象被创建,并在之后的所有数据库操作中使用此对象。
- 用途:用于指定要对哪个数据库执行操作。
2. `const char *table_name`
- 类型:`const char *`
- 描述:表示目标表的名称的字符串。`const` 修饰符表示函数不会修改传入的字符串内容。
- 用途:用于指定要将数据插入到哪个表中。表名应与数据库中已经创建的表名一致。
3. `const char *word`
- 类型:`const char *`
- 描述:表示要插入的单词的字符串。同样,`const` 修饰符表示传入的字符串内容不会在函数内被修改。
- 用途:这是插入操作中的数据部分,即将此单词插入到指定的表的相应列中。
4. `const char *meaning`
- 类型:`const char *`
- 描述:表示单词的意思的字符串。它是与单词关联的解释或定义。
- 用途:用于存储单词的解释或定义,并将其插入到表中的相应列中。
函数示例
假设我们有一个表 `words`,包含两列 `word` 和 `meaning`。以下是 `insert_into_database` 函数的示例实现:
void insert_into_database(sqlite3 *db, const char *table_name, const char *word, const char *meaning) {
char *err_msg = 0;
char sql[512];
// 创建SQL插入语句
sprintf(sql, "INSERT INTO %s (word, meaning) VALUES ('%s', '%s');", table_name, word, meaning);
// 执行SQL插入操作
int rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
// 错误处理
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
}
}
使用示例
int main() {
sqlite3 *db;
sqlite3_open("words.db", &db);
insert_into_database(db, "words", "abacus", "n. frame with beads that slide along parallel rods, used for teaching numbers to children");
sqlite3_close(db);
return 0;
}
`callback` 参数,是可以用在SQLite数据库操作中的回调函数。下面是一个有关回调函数的例子,包含参数及其解释。
回调函数的定义
假设我们定义了一个回调函数,用于在查询SQLite数据库时处理返回的结果。
int callback(void *data, int argc, char **argv, char **azColName);
参数解释
1. `void *data`
- 类型:`void *`
- 描述:用户自定义的数据指针,可以传递任何类型的数据。在调用 `sqlite3_exec` 时,可以通过该参数传递额外信息到回调函数中。如果不需要传递额外数据,可以传递 `NULL`。
- 用途:允许在回调函数中使用外部的数据或状态信息。常用于在多次回调中累积结果或传递上下文信息。
2. `int argc`
- 类型:`int`
- 描述:表示查询结果中的列数。在每次回调时,`argc` 表示当前记录的字段数(即列的数量)。
- 用途:用于遍历查询结果中的每一列,可以与 `argv` 和 `azColName` 参数配合使用来处理查询结果。
3. `char **argv`
- 类型:`char **`
- 描述:包含当前记录中每个字段的值的数组。数组中的每个元素是一个字符串,表示查询结果中的每个字段的值。如果字段的值为 `NULL`,则该元素指向 `NULL`。
- 用途:用于获取每个字段的具体值,通常在 `argc` 的范围内迭代处理。
4. `char **azColName`
- 类型:`char **`
- 描述:包含字段名的数组。数组中的每个元素是一个字符串,表示查询结果中每个字段的名称。
- 用途:用于获取每个字段的名称,与 `argv` 结合使用时,可以生成类似于 `字段名 = 字段值` 的输出格式。
回调函数的示例实现
下面是一个示例回调函数,用于打印查询结果的每一行数据:
int callback(void *data, int argc, char **argv, char **azColName) {
int i;
fprintf(stderr, "%s: \n", (const char*)data);
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
回调函数的使用
假设我们想查询数据库并使用这个回调函数来处理结果:
int main() {
sqlite3 *db;
char *err_msg = 0;
const char* data = "Callback function called";
// 打开数据库
int rc = sqlite3_open("words.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}
// 定义SQL查询
const char *sql = "SELECT * FROM words";
// 执行SQL查询并调用回调函数
rc = sqlite3_exec(db, sql, callback, (void*)data, &err_msg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
}
// 关闭数据库
sqlite3_close(db);
return 0;
}
参数总结
- `void *data`:用户传递的自定义数据,可以是任何类型的数据。
- `int argc`:查询结果的列数。
- `char **argv`:每一列的具体值。
- `char **azColName`:每一列的名称。
使用这些参数,回调函数可以灵活地处理数据库查询结果,并将结果按用户需求进行处理或显示。