与数据库协作
我们的HotDog应用程序进展顺利!我们实现了一个非常简单的后端,将用户的喜爱狗狗图片保存到本地"dogs.txt"文件中。
在实际应用中,您可能更希望将数据存储在正规的数据库中。现代数据库比文本文件强大得多!
如果您已经对数据库有一定了解,可以直接跳转到我们集成Sqlite与HotDog的章节;
选择数据库
在当今应用程序开发时代,可供选择的数据库种类繁多,每种数据库都有其独特的优势、劣势及权衡因素。对于用户数量较少的应用程序,选择一个"更简单"且易于管理的数据库即可。对于用户数量较多的应用程序,你可能需要考虑功能更强大的数据库,并借助额外工具来满足更严格的要求。
以下是一个(不完整!)的数据库列表及其简要概述:
- PostgreSQL:以强大的插件系统著称的高级数据库。
- MySQL:全球最受欢迎的开源数据库,适用于各类应用。
- SQLite:以可靠性和可嵌入性著称的简单文件型数据库引擎。
- Oracle:以企业级功能著称的高级商业数据库。
- Redis:以卓越性能著称的简单键值数据库。
- MongoDB:适用于无法用行和列表示的数据的数据库。
- SurrealDB:一种新的"全能型"数据库,结合了多种模型。
- CockroachDB:专为高可用性设计的分布式SQL数据库。
还有更多! 数据库种类繁多,各自擅长不同任务。这些可能包括:
- 关系型:传统行/列/表结构。
- 文档型:存储非结构化或松散结构化的数据块。
- 时间序列型:存储和查询随时间变化的大量数据。
- 图型:基于数据与其他数据的连接关系进行查询。
- 键值型:仅存储键值对------一种快速并发哈希表。
- 内存型:专为低延迟操作设计,通常用作缓存。
- 嵌入式:随应用程序一起发布的数据库。
对于大多数应用程序 ---除非有特殊需求 --- 我们推荐主流关系型数据库如 PostgreSQL 或 MySQL。
📣 PostgreSQL 目前是一个非常有趣的选择:它可以通过插件扩展以支持时间序列、向量、图、搜索和地理空间数据。
在某些情况下,您可能需要一个仅针对单个应用实例或用户机器的数据库。在这种情况下,您需要使用嵌入式数据库,如 SQLite 或 RocksDB。
为 HotDog 添加数据库
对于 HotDog,我们将使用 SQLite。HotDog 是一个非常简单的应用程序,并且只会有一名用户:您!
要为 HotDog 添加 SQLite 功能,我们将引入 rusqlite 仓库。请注意,rusqlite 仅用于在服务器上编译,因此我们将通过 Cargo.toml 中的"server"功能对其进行功能控制。
rust
[dependencies]
# ....
rusqlite = { version = "0.32.1", optional = true } # <--- add rusqlite
[features]
# ....
server = ["dioxus/server", "dep:rusqlite"] # <---- add dep:rusqlite
要连接到我们的数据库,我们将使用 rusqlite::Connection
。Rusqlite 连接不是线程安全的,并且每个线程只能存在一个连接,因此我们需要将其包装在 thread_locals 中。
当连接初始化时,我们将执行一个 SQL 操作来创建包含我们数据的 "dogs" 表。
rust
// The database is only available to server code
#[cfg(feature = "server")]
thread_local! {
pub static DB: rusqlite::Connection = {
// Open the database from the persisted "hotdog.db" file
let conn = rusqlite::Connection::open("hotdog.db").expect("Failed to open database");
// Create the "dogs" table if it doesn't already exist
conn.execute_batch(
"CREATE TABLE IF NOT EXISTS dogs (
id INTEGER PRIMARY KEY,
url TEXT NOT NULL
);",
).unwrap();
// Return the connection
conn
};
}
现在,在我们的 save_dog
服务器函数中,我们可以使用 SQL 将值插入数据库:
rust
#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {
DB.with(|f| f.execute("INSERT INTO dogs (url) VALUES (?1)", &[&image]))?;
Ok(())
}
应用程序启动后,您应该会在仓库目录中看到一个名为"hotdog.db"的文件。让我们保存几张狗狗的照片,然后使用数据库查看器打开该数据库。如果一切顺利,您应该能看到已保存的狗狗照片!

关于数据库和Rust的说明
虽然有许多数据库驱动,但Rust的支持可能有限。Rust仍然是Web开发的新选择。在本节中,我们将提供我们自己的(有偏见的!)关于推荐用于与数据库交互的库的意见。
还需要注意的是,有一些库的抽象层次高于原始SQL。这些被称为对象关系映射器(ORM)。Rust ORM 库将 SQL 语言映射为普通的 Rust 函数。我们通常建议直接使用 SQL,但 ORM 可以让编写某些查询更加轻松。
- Sqlx:一个简单但功能强大的 Postgres、MySQL 和 SQLite 接口。
- SeaORM:基于 Sqlx 构建的用于衍生数据库的 ORM。
- rusqlite:一个直观的 SQLite 接口,没有特殊的 ORM 魔法。
- rust-postgres:一个与 rusqlite 类似 API 的 Postgres 接口。
- Turbosql:一个非常简洁的 Sqlite 接口,支持自动派生。
我们未将 Diesel 等库列入此列表,因为 Rust 生态系统似乎已转向支持原生异步的最新项目。
还有许多我们尚未测试的库,但可能值得一试:
- firebase-rs:Firebase 客户端库
- postgrest-rs:Supabase 客户端库
- mongo-rust-driver:官方 MongoDB 客户端库
选择数据库驱动
虽然您可能只考虑少数几种数据库用于应用程序,但数据库提供商众多,各有优缺点。我们未与这些提供商有任何合作关系------这只是我们观察到在 Rust 应用中被使用的驱动列表。
您无需使用数据库驱动。数据库驱动提供付费数据库托管服务。使用这些提供商将产生费用!许多提供商提供免费层级,部分支持"按需缩减"功能,可帮助您在小型应用中节省成本。您随时可以自行托管和管理数据库。
对于流行的关系型数据库:
- GCP:提供AlloyDB(企业级Postgres)、CloudSQL(MySQL、Postgres)等。
- AWS:提供RDS、Aurora、DynamoDB等。
- PlanetScale:可靠的MySQL兼容数据库,支持分片以实现可扩展性。
- Firebase:谷歌的综合实时数据库,专为快速应用开发设计。
- Supabase:以出色仪表盘和工具集著称的托管 Postgres 服务。
- Neon:通过分离计算与存储实现零扩展的应用托管 Postgres 服务。
对于 SQLite:
- LiteFS:专为与 Fly.io 配合使用的分布式 SQLite 同步引擎。
- Turso:支持多租户的 SQLite 提供商,为每位用户维护独立隔离的数据库。
"零扩展"关系型解决方案:
- AWS Aurora
- LiteFS
我们不推荐特定的数据库提供商。
如果您拥有大量免费云信用额度,可考虑 AWS/GCP/Azure。 如果您希望使用带优秀仪表盘的 Postgres,可考虑 Supabase 或 Neon。 如果您追求简单体验,可考虑 Turso 或 LiteFS。