为你的Rust应用提供一个嵌入式的NoSQL数据库

647次阅读  |  发布于11月以前

长期以来,SQLite目前几乎是客户端数据存储的唯一选择,SQLite是一个老而稳定的软件,但它缺乏一些现代功能。然而,时代在变化,需求也在迅速变化。

在这篇文章中,我们将介绍PoloDB。PoloDB旨在为SQLite提供一种现代的替代方案,支持多线程和多会话,并保留了SQLite的嵌入式和轻量级特性。

PoloDB是一个用Rust编写的嵌入式数据库,如果你正在用Rust开发应用程序,PoloDB将非常适合你,这是因为PoloDB实现了轻量级的MongoDB,本质上与MongoDB兼容。

创建项目

创建一个Rust项目:

cargo new polodb-example

在Cargo.toml文件中加入PoloDB:

[dependencies]
polodb_core = "4.3.2"

创建数据库

PoloDB可以将数据存储在内存中;也可以将数据存储在文件中,持久化保存在磁盘上。

fn create_db(path: &str) -> Database {
    if path.is_empty() {
        Database::open_memory().unwrap()
    }else {
        Database::open_file("test-polo.db").unwrap()
    }
}

插入数据

要插入数据,请调用insert方法。插入数据之后,将返回一个InsertResult结构体。如果没有提供主键,数据库将创建一个主键,并在结果中获取它。

#[derive(Debug, Serialize, Deserialize)]
struct Book {
    title: String,
    author: String,
}

fn insert_one(db: &Database) -> InsertOneResult {
    let collection = db.collection("books");
    collection.insert_one(Book {
        title: "The Three-Body Problem".to_string(),
        author: "Liu Cixin".to_string(),
    }).unwrap()
}

在上面的示例中,Book结构被序列化为BSON格式并保存在磁盘上。由于PoloDB是无结构的,因此不需要为它创建表,它可以自由地插入任何形式的数据。

下面的例子演示插入多条数据:

fn insert_many(db: &Database) {
    let doc_collection = db.collection::<Document>("books");
    let docs = vec![
        doc! { "title": "1984", "author": "George Orwell" },
        doc! { "title": "Animal Farm", "author": "George Orwell" },
        doc! { "title": "The Great Gatsby", "author": "F. Scott Fitzgerald" },
    ];
    doc_collection.insert_many(docs).unwrap();

    let book_collection = db.collection::<Book>("books");
    let books = vec![
        Book {
            title: "The Grapes of Wrath".to_string(),
            author: "John Steinbeck".to_string(),
        },
        Book {
            title: "To Kill a Mockingbird".to_string(),
            author: "Harper Lee".to_string(),
        },
    ];
    book_collection.insert_many(books).unwrap();
}

Collection可以被参数化为任何类型,只要它实现了serde库的序列化和反序列化特性,而不仅仅是Document。

查询数据

在PoloDB中查询也非常简单,可以通过数据的字段来查询collection:

fn find(db: &Database) {
    let collection = db.collection::<Book>("books");

    let book = collection.find_one(doc! {"author": "Liu Cixin"}).unwrap();
    println!("name: {:?}", book);

    let books = collection.find(None).unwrap();
    for book in books {
        println!("name: {:?}", book);
    }
}

find()方法用于查询符合特定查询条件的文档集合。当不带参数调用find()方法时,将返回指向结果的游标,你可以操纵游标从数据库中检索数据。

如果需要更复杂的查询,可以查看PoloDB的文档。

修改数据

在PoloDB中修改一行或多行数据很容易。要修改行,需要为要修改的行提供条件,并指定如何修改它们。

fn update(db: &Database) {
    let collection = db.collection::<Book>("books");
    collection.update_one(doc! {
        "author": "Liu Cixin"
    }, doc! {
        "$set": doc! {
            "title": "The Three-Body Problem 1",
        },
    }).unwrap();

    collection.update_many(doc! {
        "author": "George Orwell"
    }, doc! {
        "$set": doc! {
            "title": "xxxxx",
        },
    }).unwrap();
}

删除数据

PoloDB提供了delete_one和delete_many方法来删除数据库中的一行或多行。只需提供正确的过滤器参数来选择要删除的行:

fn delete(db: &Database) {
    let collection = db.collection::<Book>("books");
    collection.delete_one(doc! {
        "author": "Liu Cixin"
    }).unwrap();

    collection.delete_many(doc! {
        "author": "George Orwell"
    }).unwrap();
}

总结

PoloDB是一个简单但功能强大的数据库系统,目前仍在开发中。本文演示了它的基本功能,它也有许多高级特性,如会话和事务。如果你感兴趣,可以阅读文档并尝试一下,我相信PoloDB会对你的应用有很大帮助。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8