乐闻世界logo
搜索文章和话题

Sqlite

SQLite 是一个开源软件库,它实现了独立、无服务器、零配置、事务性 SQL 数据库引擎。SQLite 是世界上部署最广泛的 SQL 数据库引擎。
Sqlite
查看更多相关内容
SQLite 的连接池如何实现?SQLite 的连接池对于提高应用性能很重要: 1. **连接池的概念** - SQLite 本身不提供内置的连接池 - 连接池需要在应用层实现 - 目的是重用数据库连接,减少创建和销毁连接的开销 2. **连接池的优势** - **提高性能**:避免频繁创建和销毁连接 - **减少资源消耗**:降低内存和 CPU 使用 - **提高并发能力**:管理有限数量的连接 - **统一配置**:集中管理连接参数 3. **实现连接池的要点** - 维护一个连接队列 - 提供获取和释放连接的方法 - 处理连接超时和错误 - 管理连接的最大数量 4. **Python 连接池示例** ```python import sqlite3 from queue import Queue class SQLiteConnectionPool: def __init__(self, db_path, max_connections=5): self.db_path = db_path self.max_connections = max_connections self.pool = Queue(max_connections) for _ in range(max_connections): self.pool.put(sqlite3.connect(db_path, check_same_thread=False)) def get_connection(self): return self.pool.get() def return_connection(self, conn): self.pool.put(conn) def close_all(self): while not self.pool.empty(): conn = self.pool.get() conn.close() ``` 5. **连接池配置参数** - 最大连接数:根据应用并发需求设置 - 最小空闲连接数:保持一定数量的空闲连接 - 连接超时时间:获取连接的最大等待时间 - 连接最大生命周期:定期刷新连接 6. **使用连接池的最佳实践** - 使用后及时释放连接 - 使用 try-finally 确保连接释放 - 处理连接异常情况 - 定期检查连接有效性 - 监控连接池使用情况 7. **连接池的挑战** - 线程安全:确保多线程环境下的安全访问 - 连接泄漏:防止连接未正确释放 - 连接过期:处理长时间未使用的连接 - 资源限制:避免创建过多连接 8. **第三方库支持** - 各语言都有成熟的连接池实现 - Python:SQLAlchemy、DBUtils - Java:HikariCP、Apache DBCP - Node.js:generic-pool 连接池是提高 SQLite 应用性能的重要技术手段。
服务端 · 2月18日 22:01
SQLite 支持哪些约束类型?SQLite 的约束机制确保数据的完整性和一致性: 1. **NOT NULL 约束** - 确保列不接受 NULL 值 - 插入或更新时如果违反约束会报错 ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL ); ``` 2. **UNIQUE 约束** - 确保列中的所有值都是唯一的 - 可以应用于单列或多列组合 - 自动创建索引以提高性能 ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, email TEXT UNIQUE ); ``` 3. **PRIMARY KEY 约束** - 唯一标识表中的每一行 - 自动创建 NOT NULL 和 UNIQUE 约束 - 可以是单列或复合主键 ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, username TEXT ); ``` 4. **FOREIGN KEY 约束** - 建立表之间的关系 - 确保引用的完整性 - 需要启用外键约束:`PRAGMA foreign_keys = ON;` ```sql CREATE TABLE orders ( id INTEGER PRIMARY KEY, user_id INTEGER, FOREIGN KEY (user_id) REFERENCES users(id) ); ``` 5. **CHECK 约束** - 定义列值必须满足的条件 - 可以包含复杂的表达式 ```sql CREATE TABLE products ( id INTEGER PRIMARY KEY, price REAL CHECK(price > 0), quantity INTEGER CHECK(quantity >= 0) ); ``` 6. **DEFAULT 约束** - 为列指定默认值 - 当插入时未提供值时使用默认值 ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, status TEXT DEFAULT 'active', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` 7. **约束冲突处理** - 使用 ON CONFLICT 子句处理约束冲突 - 可选值:ROLLBACK、ABORT、FAIL、IGNORE、REPLACE ```sql INSERT OR REPLACE INTO users (id, name) VALUES (1, 'John'); ``` 合理使用约束可以确保数据质量,防止无效数据的插入和更新。
服务端 · 2月18日 21:57
SQLite 如何处理并发访问?SQLite 的并发控制机制是其核心特性之一: 1. **锁级别** SQLite 使用不同级别的锁来管理并发访问: - **UNLOCKED**:未锁定状态 - **SHARED**:共享锁,允许多个读操作同时进行 - **RESERVED**:预留锁,表示准备写入,但仍允许读操作 - **PENDING**:等待锁,阻止新的读操作,等待现有读操作完成 - **EXCLUSIVE**:排他锁,独占访问,阻止所有其他操作 2. **读写并发模型** - **多读单写**:SQLite 支持多个读操作同时进行,但同一时间只允许一个写操作 - 读操作不会阻塞其他读操作 - 写操作需要获得排他锁,会阻塞所有其他操作 3. **事务隔离模式** ```sql -- DEFERRED(默认):第一次读操作时获取共享锁,第一次写操作时升级为排他锁 BEGIN DEFERRED TRANSACTION; -- IMMEDIATE:立即获取预留锁,防止其他写操作 BEGIN IMMEDIATE TRANSACTION; -- EXCLUSIVE:立即获取排他锁,阻止所有其他操作 BEGIN EXCLUSIVE TRANSACTION; ``` 4. **WAL 模式(Write-Ahead Logging)** - WAL 模式显著提高了并发性能 - 读操作不会阻塞写操作,写操作不会阻塞读操作 - 写操作将更改写入 WAL 文件,而不是直接修改数据库文件 - 检查点(Checkpoint)时将 WAL 文件的内容合并到主数据库文件 5. **死锁处理** - SQLite 会自动检测死锁并回滚其中一个事务 - 应用程序应捕获 `SQLITE_BUSY` 错误并重试 - 使用 `sqlite3_busy_timeout()` 设置忙等待超时 6. **并发优化建议** - 使用 WAL 模式提高并发性能 - 保持事务简短,减少锁持有时间 - 将读操作和写操作分离到不同的事务中 - 使用适当的隔离模式避免不必要的阻塞 SQLite 的并发控制机制在保证数据一致性的同时,提供了合理的并发性能,适合中小型应用的并发需求。
服务端 · 2月18日 21:51
SQLite 的窗口函数(Window Functions)如何使用?SQLite 的窗口函数(Window Functions)提供了强大的数据分析能力: 1. **窗口函数的概念** - 窗口函数对一组行执行计算,但不会将多行合并为一行 - 类似于聚合函数,但保留了原始行的详细信息 - SQLite 3.25.0+ 支持窗口函数 2. **窗口函数语法** ```sql function_name(expression) OVER ( [PARTITION BY partition_expression] [ORDER BY sort_expression] [frame_clause] ) ``` 3. **常用窗口函数** - **聚合函数**:SUM()、AVG()、COUNT()、MAX()、MIN() - **排名函数**:ROW_NUMBER()、RANK()、DENSE_RANK() - **偏移函数**:LAG()、LEAD() - **分析函数**:FIRST_VALUE()、LAST_VALUE() 4. **排名函数示例** ```sql -- ROW_NUMBER:连续排名 SELECT name, score, ROW_NUMBER() OVER (ORDER BY score DESC) as rank_num FROM students; -- RANK:相同分数相同排名,跳过后续排名 SELECT name, score, RANK() OVER (ORDER BY score DESC) as rank_num FROM students; -- DENSE_RANK:相同分数相同排名,不跳过后续排名 SELECT name, score, DENSE_RANK() OVER (ORDER BY score DESC) as rank_num FROM students; ``` 5. **偏移函数示例** ```sql -- LAG:获取前一行的值 SELECT date, sales, LAG(sales) OVER (ORDER BY date) as prev_sales, sales - LAG(sales) OVER (ORDER BY date) as growth FROM sales_data; -- LEAD:获取后一行的值 SELECT date, sales, LEAD(sales) OVER (ORDER BY date) as next_sales FROM sales_data; ``` 6. **分区示例** ```sql -- 按部门分区,计算每个部门内的排名 SELECT department, name, salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC) as dept_rank FROM employees; -- 计算每个部门的平均工资 SELECT department, name, salary, AVG(salary) OVER (PARTITION BY department) as dept_avg_salary FROM employees; ``` 7. **窗口帧(Frame)示例** ```sql -- 计算移动平均(3天) SELECT date, sales, AVG(sales) OVER ( ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) as moving_avg FROM sales_data; -- 计算累计总和 SELECT date, sales, SUM(sales) OVER ( ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) as running_total FROM sales_data; ``` 8. **实际应用场景** ```sql -- 计算销售额排名 SELECT product_name, sales_amount, RANK() OVER (ORDER BY sales_amount DESC) as sales_rank FROM sales; -- 计算同比增长 SELECT year, month, revenue, LAG(revenue) OVER (ORDER BY year, month) as prev_revenue, (revenue - LAG(revenue) OVER (ORDER BY year, month)) / LAG(revenue) OVER (ORDER BY year, month) * 100 as growth_rate FROM monthly_revenue; -- 找出每个类别的前3名产品 WITH ranked_products AS ( SELECT category, product_name, sales, RANK() OVER (PARTITION BY category ORDER BY sales DESC) as rank_num FROM products ) SELECT * FROM ranked_products WHERE rank_num <= 3; ``` 9. **窗口帧类型** - **ROWS**:基于物理行数 - **RANGE**:基于值范围 - **GROUPS**:基于分组 10. **性能优化** - 为窗口函数的 ORDER BY 和 PARTITION BY 列创建索引 - 避免在窗口函数中使用复杂表达式 - 考虑使用子查询或 CTE 优化复杂窗口函数 窗口函数是 SQLite 进行复杂数据分析的重要工具。
服务端 · 2月18日 21:51
SQLite 的扩展机制如何使用?SQLite 的扩展机制允许开发者添加自定义功能: 1. **扩展概述** - SQLite 支持通过扩展添加自定义函数、聚合函数、虚拟表等 - 扩展可以动态加载或静态链接 - 扩展使用 C/C++ 编写,遵循 SQLite 的 API 规范 2. **加载扩展** ```sql -- 启用扩展加载 PRAGMA load_extension = ON; -- 加载扩展 SELECT load_extension('extension_path'); -- 加载内置扩展(如 FTS5) SELECT load_extension('sqlite3ext'); ``` 3. **创建标量函数** ```c // C 代码示例:创建自定义函数 #include <sqlite3ext.h> SQLITE_EXTENSION_INIT1 static void my_function(sqlite3_context *context, int argc, sqlite3_value **argv) { if (argc != 1) { sqlite3_result_error(context, "Invalid argument count", -1); return; } const char *text = (const char *)sqlite3_value_text(argv[0]); // 处理逻辑... sqlite3_result_text(context, "result", -1, SQLITE_TRANSIENT); } #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_myextension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { SQLITE_EXTENSION_INIT2(pApi); sqlite3_create_function(db, "my_function", 1, SQLITE_UTF8, NULL, my_function, NULL, NULL); return SQLITE_OK; } ``` 4. **创建聚合函数** ```c // C 代码示例:创建自定义聚合函数 typedef struct { double sum; int count; } AvgCtx; static void avg_step(sqlite3_context *context, int argc, sqlite3_value **argv) { AvgCtx *p = (AvgCtx *)sqlite3_aggregate_context(context, sizeof(AvgCtx)); if (p->count == 0) { p->sum = 0; } p->sum += sqlite3_value_double(argv[0]); p->count++; } static void avg_final(sqlite3_context *context) { AvgCtx *p = (AvgCtx *)sqlite3_aggregate_context(context, sizeof(AvgCtx)); if (p->count > 0) { sqlite3_result_double(context, p->sum / p->count); } else { sqlite3_result_null(context); } } int sqlite3_myextension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { SQLITE_EXTENSION_INIT2(pApi); sqlite3_create_function(db, "my_avg", 1, SQLITE_UTF8, NULL, NULL, avg_step, avg_final); return SQLITE_OK; } ``` 5. **创建虚拟表** ```c // C 代码示例:创建虚拟表模块 typedef struct MyVtab MyVtab; struct MyVtab { sqlite3_vtab base; // 自定义数据... }; static int myCreate(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, char **pzErr) { MyVtab *pVtab = (MyVtab *)sqlite3_malloc(sizeof(MyVtab)); // 初始化虚拟表... *ppVtab = (sqlite3_vtab *)pVtab; return SQLITE_OK; } static int myConnect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, char **pzErr) { // 连接虚拟表... return SQLITE_OK; } static int myBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo) { // 优化查询计划... return SQLITE_OK; } static int myFilter(sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) { // 过滤数据... return SQLITE_OK; } static int myNext(sqlite3_vtab_cursor *pCursor) { // 移动到下一行... return SQLITE_OK; } static int myEof(sqlite3_vtab_cursor *pCursor) { // 检查是否到达末尾... return 0; } static int myColumn(sqlite3_vtab_cursor *pCursor, sqlite3_context *context, int i) { // 返回列值... return SQLITE_OK; } static int myRowid(sqlite3_vtab_cursor *pCursor, sqlite3_int64 *pRowid) { // 返回行 ID... return SQLITE_OK; } static sqlite3_module myModule = { .iVersion = 0, .xCreate = myCreate, .xConnect = myConnect, .xBestIndex = myBestIndex, .xDisconnect = myDisconnect, .xDestroy = myDestroy, .xOpen = myOpen, .xClose = myClose, .xFilter = myFilter, .xNext = myNext, .xEof = myEof, .xColumn = myColumn, .xRowid = myRowid }; int sqlite3_myextension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { SQLITE_EXTENSION_INIT2(pApi); sqlite3_create_module(db, "my_module", &myModule, 0); return SQLITE_OK; } ``` 6. **常用内置扩展** - **FTS3/FTS4/FTS5**:全文搜索 - **RTREE**:空间索引 - **STAT4**:查询优化统计 - **JSON1**:JSON 支持 - **GEOPOLY**:地理多边形 7. **扩展的应用场景** - 自定义业务逻辑函数 - 集成第三方库 - 实现特殊数据类型 - 优化特定查询模式 - 添加加密支持 8. **扩展开发注意事项** - 遵循 SQLite 的内存管理规则 - 正确处理错误情况 - 确保线程安全 - 提供完整的文档 - 进行充分的测试 9. **跨语言扩展** - Python:使用 sqlite3.create_function() - JavaScript:使用 Database.createFunction() - Java:使用 Function.create() - Go:使用 RegisterFunc() SQLite 的扩展机制提供了强大的扩展能力,使开发者能够根据需求定制数据库功能。
服务端 · 2月18日 21:51
SQLite 的生成列(Generated Columns)如何使用?SQLite 的生成列(Generated Columns)提供了一种自动计算列值的方式: 1. **生成列的概念** - 生成列的值由表达式自动计算得出 - 不能直接插入或更新生成列的值 - 分为 STORED(存储)和 VIRTUAL(虚拟)两种类型 2. **生成列类型** - **STORED**:计算结果存储在磁盘上,占用空间但查询快 - **VIRTUAL**:每次查询时计算,不占用空间但查询慢 3. **创建生成列** ```sql -- STORED 生成列 CREATE TABLE products ( id INTEGER PRIMARY KEY, name TEXT, price REAL, quantity INTEGER, total REAL GENERATED ALWAYS AS (price * quantity) STORED ); -- VIRTUAL 生成列 CREATE TABLE users ( id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT, full_name TEXT GENERATED ALWAYS AS (first_name || ' ' || last_name) VIRTUAL ); ``` 4. **生成列的约束** - 表达式必须确定,不能包含随机函数 - 不能引用其他生成列 - 不能引用同一表的其他行 - 不能包含子查询 - 不能使用非确定性函数(如 random()) 5. **使用生成列的优势** - **数据一致性**:自动保持数据同步 - **减少冗余**:避免手动维护计算字段 - **性能优化**:STORED 列可以建立索引 - **代码简化**:减少应用层计算逻辑 6. **为生成列创建索引** ```sql CREATE TABLE orders ( id INTEGER PRIMARY KEY, order_date TEXT, status TEXT, year INTEGER GENERATED ALWAYS AS (CAST(strftime('%Y', order_date) AS INTEGER)) STORED ); -- 为生成列创建索引 CREATE INDEX idx_year ON orders(year); ``` 7. **修改生成列** SQLite 不支持直接修改生成列,需要: ```sql -- 创建新表 CREATE TABLE products_new ( id INTEGER PRIMARY KEY, name TEXT, price REAL, quantity INTEGER, total REAL GENERATED ALWAYS AS (price * quantity * 1.1) STORED ); -- 迁移数据 INSERT INTO products_new (id, name, price, quantity) SELECT id, name, price, quantity FROM products; -- 删除旧表,重命名新表 DROP TABLE products; ALTER TABLE products_new RENAME TO products; ``` 8. **生成列的使用场景** - 计算字段(总价、平均值等) - 数据转换(日期格式转换、类型转换) - 数据提取(从 JSON 中提取字段) - 数据验证(检查条件) - 派生数据(基于其他列计算) 9. **性能考虑** - STORED 列:占用存储空间,查询快,写入慢 - VIRTUAL 列:不占用存储空间,查询慢,写入快 - 根据查询频率选择合适的类型 - 为频繁查询的 STORED 列创建索引 10. **与其他特性结合** - 与 JSON 扩展结合:提取 JSON 字段 - 与全文搜索结合:生成搜索文本 - 与约束结合:验证数据完整性 生成列是 SQLite 提供自动化数据维护的强大工具。
服务端 · 2月18日 21:51
SQLite 的触发器(Trigger)如何使用?SQLite 的触发器(Trigger)机制允许在特定数据库事件发生时自动执行操作: 1. **触发器类型** - **BEFORE 触发器**:在操作执行前触发 - **AFTER 触发器**:在操作执行后触发 - **INSTEAD OF 触发器**:替代原始操作执行(主要用于视图) 2. **触发事件** - INSERT:插入数据时触发 - UPDATE:更新数据时触发 - DELETE:删除数据时触发 3. **创建触发器** ```sql -- BEFORE INSERT 触发器 CREATE TRIGGER update_timestamp BEFORE INSERT ON users FOR EACH ROW BEGIN SET NEW.created_at = CURRENT_TIMESTAMP; END; -- AFTER UPDATE 触发器 CREATE TRIGGER log_update AFTER UPDATE ON users FOR EACH ROW BEGIN INSERT INTO audit_log (table_name, operation, user_id) VALUES ('users', 'UPDATE', NEW.id); END; ``` 4. **触发器中的特殊引用** - **NEW.column**:引用 INSERT 或 UPDATE 操作后的新值 - **OLD.column**:引用 UPDATE 或 DELETE 操作前的旧值 - NEW 只在 INSERT 和 UPDATE 中可用 - OLD 只在 UPDATE 和 DELETE 中可用 5. **触发器应用场景** - 自动维护时间戳字段 - 实现审计日志 - 数据验证和约束 - 级联操作 - 数据同步 6. **管理触发器** ```sql -- 查看触发器 SELECT * FROM sqlite_master WHERE type = 'trigger'; -- 删除触发器 DROP TRIGGER trigger_name; -- 列出表的触发器 PRAGMA trigger_list(table_name); ``` 7. **限制和注意事项** - 触发器不能直接调用其他触发器(递归) - 触发器执行会影响性能 - 复杂的触发器逻辑难以调试 - 避免在触发器中执行耗时操作 触发器是 SQLite 实现自动化数据维护和业务逻辑的重要工具。
服务端 · 2月18日 21:51
SQLite 的视图(View)如何使用?SQLite 的视图(View)提供了一种虚拟表的概念: 1. **视图的概念** - 视图是基于 SQL 查询结果的虚拟表 - 不存储实际数据,只存储查询定义 - 每次查询视图时都执行底层的 SQL 语句 2. **创建视图** ```sql -- 创建简单视图 CREATE VIEW user_orders AS SELECT u.id, u.name, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.name; -- 创建带过滤条件的视图 CREATE VIEW active_users AS SELECT * FROM users WHERE status = 'active'; ``` 3. **视图的优势** - **简化复杂查询**:将复杂的 JOIN 和聚合操作封装在视图中 - **数据安全性**:限制用户访问特定列或行 - **逻辑抽象**:隐藏底层表结构的变化 - **代码重用**:避免重复编写相同的查询 4. **查询视图** ```sql -- 查询视图就像查询普通表一样 SELECT * FROM user_orders WHERE order_count > 5; ``` 5. **管理视图** ```sql -- 查看视图定义 SELECT sql FROM sqlite_master WHERE type = 'view' AND name = 'user_orders'; -- 删除视图 DROP VIEW view_name; -- 修改视图(需要先删除再创建) DROP VIEW IF EXISTS user_orders; CREATE VIEW user_orders AS ...; ``` 6. **视图的限制** - SQLite 的视图是只读的(默认情况下) - 不能直接对视图执行 INSERT、UPDATE、DELETE 操作 - 可以使用 INSTEAD OF 触发器实现可更新视图 ```sql CREATE TRIGGER update_user_orders INSTEAD OF UPDATE ON user_orders BEGIN UPDATE users SET name = NEW.name WHERE id = NEW.id; END; ``` 7. **视图的使用场景** - 报表和数据分析 - 数据权限控制 - 简化应用层的查询逻辑 - 跨表查询的抽象 8. **性能考虑** - 视图本身不存储数据,每次查询都执行底层 SQL - 复杂视图可能影响查询性能 - 可以考虑使用物化视图(通过表定期刷新) 视图是 SQLite 提供数据抽象和安全控制的重要机制。
服务端 · 2月18日 21:51
什么是 SQLite 的预编译语句?如何使用?SQLite 的预编译语句(Prepared Statements)是提高性能和安全性的重要机制: 1. **预编译语句的概念** - 预编译语句是 SQL 模板,包含参数占位符 - SQL 语句只编译一次,可以多次执行 - 参数值在执行时绑定,而不是编译时 2. **预编译语句的优势** - **性能提升**:避免重复解析和编译 SQL - **防止 SQL 注入**:参数化查询自动转义特殊字符 - **代码可读性**:SQL 语句更清晰易读 - **类型安全**:参数类型自动处理 3. **使用预编译语句** ```python # Python 示例 import sqlite3 conn = sqlite3.connect('database.db') cursor = conn.cursor() # 创建预编译语句 stmt = "INSERT INTO users (name, email) VALUES (?, ?)" # 多次执行 users = [('Alice', 'alice@example.com'), ('Bob', 'bob@example.com')] cursor.executemany(stmt, users) conn.commit() ``` 4. **参数占位符** - **问号占位符(?)**:SQLite 标准占位符 - **命名占位符(:name)**:使用名称引用参数 ```sql -- 问号占位符 SELECT * FROM users WHERE id = ? AND status = ? -- 命名占位符 SELECT * FROM users WHERE id = :id AND status = :status ``` 5. **预编译语句的生命周期** - 准备(Prepare):编译 SQL 语句 - 绑定(Bind):设置参数值 - 执行(Execute):执行语句 - 重置(Reset):重置语句以便再次执行 - 释放(Finalize):释放语句资源 6. **性能优化技巧** - 在循环外准备语句,循环内执行 - 使用 executemany 批量操作 - 重用预编译语句而不是每次重新创建 - 及时释放不再使用的语句 7. **安全最佳实践** - 始终使用参数化查询,避免字符串拼接 - 不要将用户输入直接拼接到 SQL 中 - 验证参数类型和范围 - 使用最小权限原则 8. **不同语言的实现** - Python:sqlite3 模块的 execute() 和 executemany() - Java:PreparedStatement 接口 - C/C++:sqlite3_prepare_v2() 和 sqlite3_bind_*() - Node.js:db.prepare() 和 stmt.run() 预编译语句是 SQLite 开发中不可或缺的技术,既提高了性能又增强了安全性。
服务端 · 2月18日 21:51
SQLite 的索引机制如何影响查询性能?SQLite 的索引机制对查询性能有重要影响: 1. **索引类型** - **B-Tree 索引**:默认索引类型,适合范围查询和排序 - **哈希索引**:仅在内存数据库中可用,适合等值查询 - **R-Tree 索引**:用于空间数据,支持地理信息查询 - **全文索引(FTS)**:用于全文搜索功能 2. **索引创建** ```sql -- 创建单列索引 CREATE INDEX idx_name ON table_name(column_name); -- 创建复合索引 CREATE INDEX idx_composite ON table_name(col1, col2); -- 创建唯一索引 CREATE UNIQUE INDEX idx_unique ON table_name(column_name); ``` 3. **索引使用原则** - 在 WHERE 子句、JOIN 条件、ORDER BY、GROUP BY 中频繁使用的列上创建索引 - 选择性高的列(唯一值多)更适合建索引 - 避免在小表上创建索引 - 复合索引遵循最左前缀原则 4. **索引优化技巧** - 使用 `EXPLAIN QUERY PLAN` 分析查询执行计划 - 避免在索引列上使用函数或表达式 - 使用 `LIKE 'prefix%'` 可以利用索引,`LIKE '%suffix'` 不能 - 合理使用覆盖索引(Covering Index)避免回表 5. **索引维护** - 索引会增加 INSERT、UPDATE、DELETE 操作的开销 - 定期使用 `ANALYZE` 命令更新统计信息 - 使用 `REINDEX` 重建碎片化的索引 - 删除不再使用的索引以节省空间和提高写入性能 6. **主键和自动索引** - 创建表时声明 PRIMARY KEY 会自动创建唯一索引 - UNIQUE 约束也会自动创建索引 - WITHOUT ROWID 表可以避免创建隐藏的 rowid 索引 合理使用索引可以显著提高查询性能,但需要在查询性能和写入性能之间找到平衡。
服务端 · 2月18日 21:50