面试题答案
一键面试使用事务确保数据一致性和完整性
- 开始事务:在iOS开发中,使用SQLite3框架进行数据库操作。在执行复杂操作前,通过执行
BEGIN TRANSACTION
语句开始一个事务。例如,在Objective-C中:
const char *sql = "BEGIN TRANSACTION";
if (sqlite3_exec(database, sql, NULL, NULL, &errorMsg) != SQLITE_OK) {
NSLog(@"Failed to start transaction: %s", errorMsg);
sqlite3_free(errorMsg);
}
在Swift中:
let sql = "BEGIN TRANSACTION"
var error: UnsafeMutablePointer<sqlite3_stmt>?
if sqlite3_prepare_v2(database, sql, -1, &error, nil) == SQLITE_OK {
if sqlite3_step(error) != SQLITE_DONE {
print("Failed to start transaction")
}
sqlite3_finalize(error)
} else {
print("Failed to prepare start transaction statement")
}
- 执行操作:依次执行批量插入、更新多条记录等复杂操作。例如批量插入数据,在Objective-C中:
for (NSDictionary *dataDict in dataArray) {
const char *sql = "INSERT INTO your_table (column1, column2) VALUES (?,?)";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, [dataDict[@"value1"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, [dataDict[@"value2"] UTF8String], -1, SQLITE_TRANSIENT);
if (sqlite3_step(stmt) != SQLITE_DONE) {
NSLog(@"Failed to insert data");
}
sqlite3_finalize(stmt);
} else {
NSLog(@"Failed to prepare insert statement");
}
}
在Swift中:
for dataDict in dataArray {
let sql = "INSERT INTO your_table (column1, column2) VALUES (?,?)"
var stmt: OpaquePointer?
if sqlite3_prepare_v2(database, sql, -1, &stmt, nil) == SQLITE_OK {
if let value1 = dataDict["value1"] as? String {
sqlite3_bind_text(stmt, 1, value1, -1, nil)
}
if let value2 = dataDict["value2"] as? String {
sqlite3_bind_text(stmt, 2, value2, -1, nil)
}
if sqlite3_step(stmt) != SQLITE_DONE {
print("Failed to insert data")
}
sqlite3_finalize(stmt)
} else {
print("Failed to prepare insert statement")
}
}
- 提交事务:如果所有操作都成功,通过执行
COMMIT TRANSACTION
语句提交事务,使所有更改持久化。在Objective-C中:
const char *sql = "COMMIT TRANSACTION";
if (sqlite3_exec(database, sql, NULL, NULL, &errorMsg) != SQLITE_OK) {
NSLog(@"Failed to commit transaction: %s", errorMsg);
sqlite3_free(errorMsg);
}
在Swift中:
let sql = "COMMIT TRANSACTION"
var error: UnsafeMutablePointer<sqlite3_stmt>?
if sqlite3_prepare_v2(database, sql, -1, &error, nil) == SQLITE_OK {
if sqlite3_step(error) != SQLITE_DONE {
print("Failed to commit transaction")
}
sqlite3_finalize(error)
} else {
print("Failed to prepare commit transaction statement")
}
- 回滚事务:如果在操作过程中出现任何错误,通过执行
ROLLBACK TRANSACTION
语句回滚事务,撤销所有未提交的更改。在Objective-C中:
const char *sql = "ROLLBACK TRANSACTION";
if (sqlite3_exec(database, sql, NULL, NULL, &errorMsg) != SQLITE_OK) {
NSLog(@"Failed to rollback transaction: %s", errorMsg);
sqlite3_free(errorMsg);
}
在Swift中:
let sql = "ROLLBACK TRANSACTION"
var error: UnsafeMutablePointer<sqlite3_stmt>?
if sqlite3_prepare_v2(database, sql, -1, &error, nil) == SQLITE_OK {
if sqlite3_step(error) != SQLITE_DONE {
print("Failed to rollback transaction")
}
sqlite3_finalize(error)
} else {
print("Failed to prepare rollback transaction statement")
}
大数据量下的优化措施
- 批量操作:不要一条一条地插入或更新数据,而是将多条数据组成一批进行操作。减少数据库的I/O次数,提高性能。例如,每次批量插入1000条数据。
- 索引优化:为经常用于查询、排序、连接的字段创建索引。索引可以加快查询速度,但会增加插入、更新操作的开销,所以要权衡使用。例如,如果经常根据某个字段查询数据,就为该字段创建索引:
CREATE INDEX idx_column_name ON your_table (column_name);
- 事务合并:如果有多个小事务,可以尝试合并成一个大事务,但要注意大事务可能会锁定数据库较长时间,影响其他操作。
- 分页处理:在查询大数据量时,采用分页技术,每次只获取一部分数据,减少内存占用和处理时间。例如,使用
LIMIT
和OFFSET
子句:
SELECT * FROM your_table LIMIT 10 OFFSET 0; -- 获取前10条数据
- 缓存机制:对于经常访问的数据,可以在内存中设置缓存,减少对数据库的直接访问。例如,使用
NSCache
(Objective-C)或Cache
(Swift)来缓存数据。 - 数据库配置优化:根据应用场景,合理配置SQLite数据库的缓存大小等参数。可以通过
sqlite3_db_config
函数来设置一些配置选项。例如,增大缓存大小:
sqlite3_db_config(database, SQLITE_DBCONFIG_MMAP_SIZE, 1024 * 1024 * 100, NULL); // 设置100MB的内存映射缓存
在Swift中:
sqlite3_db_config(database, SQLITE_DBCONFIG_MMAP_SIZE, 1024 * 1024 * 100, nil)