数据库开发: SQLite 初学者教程:由浅入深 - C#、 Node.js 、Python集成

SQLite 初学者教程:由浅入深

SQLite 是一个轻量级的关系型数据库,广泛应用于嵌入式系统、桌面应用和移动应用中。它的优势在于其小巧、独立和零配置,适合初学者以及需要在本地存储数据的应用场景。微信客户端,爱手机上用的就是SQLite,

SQLite 在微信中的具体应用场景

  1. 聊天记录:微信会将用户的聊天记录存储在本地 SQLite 数据库中,以便快速加载历史消息。聊天记录的结构化存储方式使得查询、筛选和删除变得更加高效。

  2. 联系人和群聊信息:微信的联系人、群聊、公众号订阅等信息会被存储在本地 SQLite 数据库中。这样做能提高启动速度并减少对服务器的依赖。

  3. 缓存数据:微信会缓存很多内容,如朋友圈的图片、视频、动态等。SQLite 可以用来管理这些缓存,以确保快速访问和同步。

  4. 历史数据的本地保存和同步:当微信无法连接到网络时,它仍然能够在本地保存操作记录(如发送消息等),等网络恢复后再与服务器同步。这也依赖于 SQLite 作为本地存储。

今天我们一起来学习一下基于C#的SQLite应用。


1. SQLite 简介

SQLite 是一个轻量级的数据库,它将整个数据库存储在一个文件中,并不需要一个独立的数据库服务进程。相比传统的数据库管理系统,SQLite 对于小型项目或开发过程中进行快速原型设计非常有用。

  • 小巧高效:SQLite 是一个 C 语言库,体积小,易于集成。
  • 无需配置:不需要安装数据库服务,所有数据存储在一个 .db 文件中。
  • 跨平台支持:支持多种操作系统,包括 Windows、Linux、macOS、iOS、Android。

2. 安装 SQLite

SQLite 不需要安装专门的服务器。你只需要下载 SQLite 的可执行文件或者使用一个 SQLite 客户端进行交互。

在 Windows 上安装 SQLite:
  1. 下载 SQLite 官方 Windows 预编译二进制文件:SQLite 下载页面
  2. 下载 sqlite-tools-win32-x86-xxxxxx.zip 文件。
  3. 解压并将 sqlite3.exe 放到一个方便的目录中,例如 C:\sqlite
在 macOS 上安装 SQLite:

通过 Homebrew 安装:

brew install sqlite
在 Linux 上安装 SQLite:

在基于 Debian 的系统(如 Ubuntu)上使用以下命令:

sudo apt-get install sqlite3

3. SQLite 基础操作

创建数据库

SQLite 会自动创建一个数据库文件(例如 mydatabase.db)。如果文件不存在,SQLite 会自动创建它。

sqlite3 mydatabase.db

sqlite3 mydatabase.dbSQLite 命令行工具 的使用命令,而不是某种编程语言的代码。它用于启动 SQLite 的交互式命令行界面并连接到指定的 SQLite 数据库文件(在这个例子中是 mydatabase.db)。

具体解释:

  • sqlite3:这是 SQLite 的命令行工具,允许你与 SQLite 数据库进行交互,执行 SQL 查询、创建表、插入数据等操作。
  • mydatabase.db:这是你希望打开的 SQLite 数据库文件。如果文件不存在,SQLite 会自动创建一个空的数据库文件。

使用示例:

  1. 启动 SQLite 命令行工具: 打开终端或命令提示符,输入以下命令来启动 SQLite 的交互模式:

    sqlite3 mydatabase.db
    

    这样,你就进入了 SQLite 的交互式命令行界面,并且打开了名为 mydatabase.db 的数据库。如果文件不存在,SQLite 会创建一个空数据库文件。

  2. 执行 SQL 查询: 进入命令行后,你可以输入 SQL 语句进行数据库操作,例如:

    CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);
    INSERT INTO users (name, age) VALUES ('Alice', 30);
    SELECT * FROM users;
    
  3. 退出 SQLite 命令行工具: 输入 .exit 或按 Ctrl + D 来退出命令行界面:

    .exit
    

创建表

表是数据库的基础结构,可以用来存储数据。以下是创建一个简单的用户表的示例:

CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    age INTEGER
);
  • id 是主键,AUTOINCREMENT 会自动为每一行分配一个唯一的值。
  • name 是用户的名字,不允许为空。
  • age 是用户的年龄,允许为空。
插入数据

插入数据的 SQL 语句如下:

INSERT INTO users (name, age) VALUES ('Alice', 30);
INSERT INTO users (name, age) VALUES ('Bob', 25);

你可以使用 INSERT INTO 来将数据插入到表中。

查询数据

查询数据是通过 SELECT 语句实现的:

SELECT * FROM users;

这将返回 users 表中所有的数据。如果你想要根据条件查询数据,可以使用 WHERE 子句:

SELECT * FROM users WHERE age > 25;
更新数据

使用 UPDATE 语句来修改表中的数据:

UPDATE users SET age = 26 WHERE name = 'Bob';

这条语句会将 Bob 的年龄更新为 26。

删除数据

使用 DELETE 语句来删除数据:

DELETE FROM users WHERE name = 'Alice';

这会删除名字为 Alice 的记录。


4. SQLite 高级操作

事务操作

SQLite 支持事务操作,以保证数据的完整性。你可以通过 BEGIN TRANSACTIONCOMMITROLLBACK 来管理事务。

BEGIN TRANSACTION;

INSERT INTO users (name, age) VALUES ('Charlie', 28);
UPDATE users SET age = 29 WHERE name = 'Bob';

COMMIT;

如果事务过程中出现错误,可以回滚:

ROLLBACK;
限制和分页

SQLite 提供了 LIMITOFFSET 来限制查询结果的数量,适用于分页查询。

SELECT * FROM users LIMIT 2 OFFSET 2;

这将跳过前两行数据,返回接下来的两行数据。


5. SQLite 与 C# 集成

在 C# 中使用 SQLite,首先需要安装 SQLite 的 NuGet 包。推荐使用 System.Data.SQLite

安装 NuGet 包

在 Visual Studio 中,通过 NuGet 包管理器安装 System.Data.SQLite

Install-Package System.Data.SQLite
基本操作示例
  1. 连接数据库

using System;
using System.Data.SQLite;

class Program
{
    static void Main()
    {
        string connectionString = "Data Source=mydatabase.db;Version=3;";
        using (SQLiteConnection conn = new SQLiteConnection(connectionString))
        {
            conn.Open();
            
            // 执行其他数据库操作
        }
    }
}
  1. 创建表

using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
    conn.Open();
    string createTableQuery = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER)";
    SQLiteCommand cmd = new SQLiteCommand(createTableQuery, conn);
    cmd.ExecuteNonQuery();
}
  1. 插入数据
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
    conn.Open();
    string insertQuery = "INSERT INTO users (name, age) VALUES (@name, @age)";
    SQLiteCommand cmd = new SQLiteCommand(insertQuery, conn);
    cmd.Parameters.AddWithValue("@name", "Alice");
    cmd.Parameters.AddWithValue("@age", 30);
    cmd.ExecuteNonQuery();
}
  1. 查询数据

using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
    conn.Open();
    string selectQuery = "SELECT * FROM users";
    SQLiteCommand cmd = new SQLiteCommand(selectQuery, conn);
    SQLiteDataReader reader = cmd.ExecuteReader();
    
    while (reader.Read())
    {
        Console.WriteLine($"ID: {reader["id"]}, Name: {reader["name"]}, Age: {reader["age"]}");
    }
}

6. SQLite 与 Python 集成

        (1. 安装 SQLite

Python 的标准库中已经内置了 sqlite3 模块,因此你不需要额外安装任何包。你只需要确保你的 Python 环境中已经安装了 sqlite3,绝大部分情况下,Python 默认都会包含此模块。

你可以通过以下命令来验证是否安装:

python -c "import sqlite3; print(sqlite3.version)"

如果没有报错并显示 SQLite 的版本号,说明你的 Python 环境已经包含了 sqlite3


       (2. 基础操作

在 Python 中操作 SQLite 数据库的基本流程和 SQL 语法相似,使用的是 sqlite3 模块。下面介绍如何在 Python 中进行一些基础的 SQLite 操作。

连接数据库

使用 sqlite3.connect() 方法连接到 SQLite 数据库。如果数据库文件不存在,SQLite 会自动创建一个新的数据库文件。

import sqlite3

# 连接到 SQLite 数据库(如果文件不存在,会自动创建)
conn = sqlite3.connect('mydatabase.db')

# 创建一个游标对象,用于执行 SQL 语句
cursor = conn.cursor()
创建表

可以通过执行 SQL 语句来创建数据库表。下面是一个创建 users 表的示例:

cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    age INTEGER
)
''')
  • id 是主键,并且使用了 AUTOINCREMENT 自动递增。
  • name 是用户的名字,不能为 NULL
  • age 是用户的年龄,可以为空。
插入数据

插入数据时,我们可以使用 INSERT INTO 语句。为了防止 SQL 注入攻击,我们推荐使用参数化查询。

cursor.execute('''
INSERT INTO users (name, age) VALUES (?, ?)
''', ('Alice', 30))

# 或者插入多条数据
cursor.executemany('''
INSERT INTO users (name, age) VALUES (?, ?)
''', [('Bob', 25), ('Charlie', 35)])

# 提交事务
conn.commit()
查询数据

查询数据时,使用 SELECT 语句,并通过游标对象执行。查询结果通常会以元组的形式返回。

cursor.execute('SELECT * FROM users')

# 获取所有查询结果
rows = cursor.fetchall()

for row in rows:
    print(f'ID: {row[0]}, Name: {row[1]}, Age: {row[2]}')
更新数据

更新数据时,我们可以使用 UPDATE 语句。下面的示例演示了如何根据用户的名字更新年龄。

cursor.execute('''
UPDATE users SET age = ? WHERE name = ?
''', (26, 'Bob'))

# 提交事务
conn.commit()
删除数据

删除数据时,我们可以使用 DELETE 语句。

cursor.execute('''
DELETE FROM users WHERE name = ?
''', ('Alice',))

# 提交事务
conn.commit()

        (3. 事务管理

SQLite 事务的管理与其他数据库类似,使用 commit() 提交事务,使用 rollback() 回滚事务。

try:
    # 开始事务
    conn.execute('BEGIN')

    # 执行多条 SQL 语句
    cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('David', 40))
    cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Eve', 22))

    # 提交事务
    conn.commit()
except Exception as e:
    # 如果发生错误,回滚事务
    print(f"Error: {e}")
    conn.rollback()

        (4. 使用 with 语句自动管理连接

Python 的 sqlite3 模块支持使用 with 语句来自动管理数据库连接和事务。使用 with 可以确保在操作完成后自动关闭数据库连接,避免资源泄露。

import sqlite3

# 使用 `with` 自动管理数据库连接和事务
with sqlite3.connect('mydatabase.db') as conn:
    cursor = conn.cursor()

    # 创建表
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        age INTEGER
    )
    ''')

    # 插入数据
    cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Alice', 30))
    cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))

    # 查询数据
    cursor.execute('SELECT * FROM users')
    rows = cursor.fetchall()

    for row in rows:
        print(f'ID: {row[0]}, Name: {row[1]}, Age: {row[2]}')
  • with 语句中,Python 会自动管理连接的开启与关闭。
  • 即使发生异常,with 语句也会确保数据库连接被正确关闭。

       (5. 查询结果的处理

sqlite3 提供了几种不同的方式来处理查询结果。

  • fetchall():返回所有查询结果。
  • fetchone():返回一条查询结果。
  • fetchmany(n):返回前 n 条查询结果。

例如:

cursor.execute('SELECT * FROM users')
# 获取单条记录
row = cursor.fetchone()
if row:
    print(f'ID: {row[0]}, Name: {row[1]}, Age: {row[2]}')

# 获取前 2 条记录
rows = cursor.fetchmany(2)
for row in rows:
    print(f'ID: {row[0]}, Name: {row[1]}, Age: {row[2]}')

        (6. SQLite 与 Python 其他库的结合

SQLite 作为一种轻量级的数据库,不仅可以单独使用,还可以与 Python 中的许多其他库结合使用,比如:

  • Pandas:将 SQLite 数据库中的数据加载到 Pandas DataFrame 中进行分析。
  • SQLAlchemy:通过 SQLAlchemy ORM 管理 SQLite 数据库中的数据(与关系数据库无关的高级数据库操作)。

总结

通过 Python 内置的 sqlite3 模块,集成 SQLite 数据库变得非常简便。在这个教程中,我们从连接数据库、创建表、插入查询数据到事务管理都进行了详细介绍。Python 和 SQLite 的结合可以帮助开发者轻松实现本地数据存储,适用于需要高效存储和查询的小型应用程序。

如果你有更多关于 Python 和 SQLite 的问题,随时欢迎继续提问!

7.SQLite与Node.js集成

是的,Node.js 中也有非常方便的方式来集成 SQLite。通过第三方模块,你可以在 Node.js 应用中使用 SQLite 数据库。最常用的模块是 sqlite3,它是一个 Node.js 的 SQLite3 客户端,可以让你轻松地连接、查询和管理 SQLite 数据库。

(1. 安装 sqlite3 模块

在 Node.js 中使用 SQLite,首先你需要安装 sqlite3 模块。可以通过 npm 来安装:

npm install sqlite3

(2. 基本操作示例

以下是如何在 Node.js 中使用 sqlite3 模块来执行 SQLite 数据库的基本操作。

(2.1 连接数据库

首先,你需要在你的 Node.js 程序中引入 sqlite3 模块,并创建数据库连接。如果数据库文件不存在,sqlite3 会自动创建一个新的数据库文件。

const sqlite3 = require('sqlite3').verbose();

// 创建或打开数据库(如果文件不存在会创建)
let db = new sqlite3.Database('mydatabase.db', (err) => {
  if (err) {
    console.error('数据库连接失败:', err.message);
  } else {
    console.log('成功连接到数据库');
  }
});
(2.2 创建表

可以通过 run() 方法执行 SQL 语句来创建表。

const createTableQuery = `
CREATE TABLE IF NOT EXISTS users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  age INTEGER
);`;

db.run(createTableQuery, (err) => {
  if (err) {
    console.error('创建表失败:', err.message);
  } else {
    console.log('表创建成功');
  }
});
(2.3 插入数据

使用 run() 方法插入数据。如果你需要使用参数化查询,可以防止 SQL 注入问题。

const insertQuery = 'INSERT INTO users (name, age) VALUES (?, ?)';

db.run(insertQuery, ['Alice', 30], function(err) {
  if (err) {
    console.error('插入数据失败:', err.message);
  } else {
    console.log(`成功插入记录,ID 为:${this.lastID}`);
  }
});
(2.4 查询数据

查询数据可以使用 all()get() 方法。all() 返回所有匹配的记录,而 get() 只返回第一条记录。

const selectQuery = 'SELECT * FROM users';

db.all(selectQuery, [], (err, rows) => {
  if (err) {
    console.error('查询数据失败:', err.message);
  } else {
    rows.forEach((row) => {
      console.log(`${row.id}: ${row.name} - ${row.age}`);
    });
  }
});

或者,如果你只想获取一条记录,可以使用 get()

db.get('SELECT * FROM users WHERE name = ?', ['Alice'], (err, row) => {
  if (err) {
    console.error('查询失败:', err.message);
  } else {
    console.log(`找到用户:${row.name}, 年龄:${row.age}`);
  }
});
(2.5 更新数据

可以使用 run() 方法来执行 UPDATE 操作:

const updateQuery = 'UPDATE users SET age = ? WHERE name = ?';

db.run(updateQuery, [26, 'Bob'], function(err) {
  if (err) {
    console.error('更新数据失败:', err.message);
  } else {
    console.log(`成功更新了 ${this.changes} 条记录`);
  }
});
(2.6 删除数据

删除数据时也使用 run() 方法:

const deleteQuery = 'DELETE FROM users WHERE name = ?';

db.run(deleteQuery, ['Alice'], function(err) {
  if (err) {
    console.error('删除数据失败:', err.message);
  } else {
    console.log(`成功删除了 ${this.changes} 条记录`);
  }
});
(2.7 关闭数据库连接

当完成所有数据库操作后,应该关闭数据库连接。

db.close((err) => {
  if (err) {
    console.error('关闭数据库失败:', err.message);
  } else {
    console.log('数据库连接已关闭');
  }
});

(3. 事务处理

在 SQLite 中,事务(transaction)是将多个操作作为一个单独的单元进行处理。你可以使用事务来确保一组操作的原子性。

db.serialize(() => {
  // 开始事务
  db.run("BEGIN TRANSACTION");

  db.run('INSERT INTO users (name, age) VALUES (?, ?)', ['Charlie', 28]);
  db.run('INSERT INTO users (name, age) VALUES (?, ?)', ['David', 22]);

  // 提交事务
  db.run("COMMIT");
});

如果发生错误,你可以回滚事务:

db.serialize(() => {
  // 开始事务
  db.run("BEGIN TRANSACTION");

  db.run('INSERT INTO users (name, age) VALUES (?, ?)', ['Eve', 30], function(err) {
    if (err) {
      console.error('发生错误,回滚事务');
      db.run("ROLLBACK");
    }
  });

  // 提交事务
  db.run("COMMIT");
});

(4. 使用 Promiseasync/await 处理 SQLite 操作

sqlite3 是基于回调的,因此你可能希望将其封装成 Promise 以便使用 async/await,这能使代码更加简洁。

(4.1 封装为 Promise

可以通过 util.promisify() 将回调转换为 Promise,从而使用 async/await 进行数据库操作。

const { promisify } = require('util');
const sqlite3 = require('sqlite3').verbose();

let db = new sqlite3.Database('mydatabase.db');

// 将 db.all 和 db.run 封装为 Promise
const dbAll = promisify(db.all.bind(db));
const dbRun = promisify(db.run.bind(db));

async function runDatabaseOperations() {
  try {
    await dbRun('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER)');
    await dbRun('INSERT INTO users (name, age) VALUES (?, ?)', ['Alice', 30]);
    
    const rows = await dbAll('SELECT * FROM users');
    rows.forEach(row => {
      console.log(`${row.id}: ${row.name} - ${row.age}`);
    });
  } catch (err) {
    console.error('数据库操作失败:', err.message);
  } finally {
    db.close();
  }
}

runDatabaseOperations();

(5. 使用 better-sqlite3 模块

除了 sqlite3,另一个常用的 Node.js SQLite 库是 better-sqlite3,它提供了更高效、更易用的 API,尤其在处理大量数据时表现更好。

可以通过以下命令安装:

npm install better-sqlite3

然后使用如下代码:

const Database = require('better-sqlite3');
const db = new Database('mydatabase.db');

// 创建表
db.prepare('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)').run();

// 插入数据
const insert = db.prepare('INSERT INTO users (name, age) VALUES (?, ?)');
insert.run('Alice', 30);

// 查询数据
const rows = db.prepare('SELECT * FROM users').all();
console.log(rows);

// 关闭数据库
db.close();

better-sqlite3 在查询效率和使用便捷性方面通常表现得比 sqlite3 更好,尤其是在进行大量同步操作时。


总结

Node.js 中可以通过 sqlite3better-sqlite3 等模块来轻松集成 SQLite,进行本地数据库存储。无论是简单的数据插入、查询,还是事务操作,都可以通过这些模块实现。better-sqlite3 提供了一个更高效、更直观的接口,适用于需要高性能的应用场景。

8.SQLite 常见问题与优化建议

常见问题
  1. 数据库文件丢失:SQLite 数据库是一个单独的文件,因此如果文件丢失,数据也会丢失。确保备份数据库文件。
  2. 并发操作:SQLite 是一个轻量级数据库,虽然支持并发读取,但对于写操作,它会进行排队处理。因此,在高并发写入的场景下,它的性能可能受到影响。
  3. 事务处理:在批量操作时,使用事务可以显著提高效率并保证数据的完整性。
优化建议
  1. 使用索引:如果查询某些列频繁,可以考虑为这些列创建索引。
  2. 避免频繁打开和关闭连接:可以考虑将数据库连接保持在内存中,特别是在多次操作数据库时。
  3. 按需查询:对于数据量大的表,可以避免一次性查询所有数据,使用分页查询或只查询必要字段。

总结

SQLite 是一个强大且易于使用的数据库,特别适合于小型项目和嵌入式应用程序。通过本教程,你已经学习了 SQLite 的基础操作以及如何在 C# 中集成 SQLite 进行数据存储。掌握了这些基础,接下来你可以在实际项目中根据需要进行扩展,优化查询和处理数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值