# kvlite | 轻量级 NoSQL 数据库

-   通过更简单的 API 使用 SQLite
-   提供类似 MongoDB 的 API
-   更方便的创建索引
-   支持 NodeJS/better-sqlite3 和 Bun/sqlite 2 种环境

## 基本使用

使用 `Kvlite` 类创建或打开一个数据库文件，然后使用 `useCollection()` 和 `useArray()` 方法创建或打开集合或数组。

> 集合和数组在数据库中就是单独的表，数据以 JSON 格式存储。

```ts
import { Kvlite } from "fzz/src/only/kvlite"

let kv = new Kvlite("./test.db")
let collection = kv.useCollection("users")
collection.set("id123", { name: "Alice", age: 30 })
let user = collection.get("id123")

let array = kv.useArray("codes")
array.push("code1")
array.push("code2")
let code = array.get(0)

kv.close()
```

### 推荐使用 `useKvlite()` 获取 Kvilite 实例

如果要在应用生命周期中多次使用同一个数据库文件，推荐使用 `useKvlite()` 方法获取单例。
并且 `useKvlite()` 会根据运行环境自动选择合适的 SQLite 实现，例如在 Bun 环境下会使用 Bun 自带的 sqlite 模块。
为了实现兼容 Bun 的特性，`useKvlite()` 是一个异步方法。

```ts
import { useKvlite } from "fzz/src/only/kvlite"
let kv = await useKvlite("./test.db")
let collection = kv.useCollection("users")
```

## 直接使用数据结构

使用 `Kvlite` 需要打开数据库后再获取集合或数组，如果你只需要使用单个集合或数组，可以直接使用 `useKvMap()` 或 `useKvArray()` 方法，直接获取数据结构实例。

```ts
import { useKvMap, useKvArray } from "fzz/src/only/kvlite"
let users = await useKvMap("./userTable.db")
let codes = await useKvArray("./codeArray.db")
```

## 索引

你可以为 JSON 对象的字段创建索引，从而大幅提升查询性能。
不用担心 `defineIndex()` 会重复创建索引，当索引已经存在时会自动忽略。

```ts
let collection = useKvlite("./test.db").useCollection("users")
collection.defineIndex({
    id: { unique: true },
    name: true,
    date: true,
    index: true,
    desc: false, // false 表示不需要索引，如果有索引就会删除它
})
```

索引创建后，查询性能对比：

```
┌────────────────┬──────────────┬──────────────┐
│ 字段           │ 有索引       │ 无索引       │
├────────────────┼──────────────┼──────────────┤
│ 'id'           │ '0.493 ms'   │ '217.105 ms' │
│ 'name'         │ '0.230 ms'   │ '213.653 ms' │
│ 'index'        │ '0.288 ms'   │ '231.769 ms' │
│ 'index_number' │ '0.306 ms'   │ '232.920 ms' │
│ 'date'         │ '0.469 ms'   │ '223.247 ms' │
│ 'desc'         │ '255.593 ms' │ '260.713 ms' │
└────────────────┴──────────────┴──────────────┘
```

## 操作

### Collection 基本操作

### Array 基本操作

## 高性能的使用数据库

最快的使用 kvlite 的方式是把数据库放在内存中，使用 `useKvMap(":memory:")`，在合适的时候使用 `store.toBuffer()` 导出为 sqlite 的数据库文件。

注意：使用 `useKvMap(":memory:")` 每次得到的实例都是相同的，要创建不同的可以用不同的名称 `:memory:1`、`:memory:2` 等。

这适合数据总量在可用内存范围内的场景。

```js
import { useKvMap } from "kvlite"

const store = useKvMap(":memory:")
const buffer = await store.toBuffer()
```

#### 内存数据库性能对比

赋值 1_000_000 条数据到数据库的性能对比：

| 方式                                       | 时间    |
| ------------------------------------------ | ------- |
| `useKvMap(":memory:")`                     | 1.813s  |
| `useKvMap("/test.db")`                     | 14.477s |
| `useKvMap("/test.db", { fastMode: true })` | 9.691s  |
