像 SQL 中那样使用 Dexie.js (IndexedDB) 复合主键?

rea*_*iwi 3 indexeddb typescript

如何创建由多个值(例如“id”和“date”)组成的复合键(主键)?

以 SQL 为例:

PRIMARY KEY (name, date)
Run Code Online (Sandbox Code Playgroud)

到目前为止,我总是创建一个单独的、实际上无用的主键(打字稿):

export class Database extends Dexie {
item: Dexie.Table<IItem, number>;

constructor() {
    super('db');
    this.version(1).stores({
        items: '++id, name, date, description, value'
    });

    this.items = this.table('items');
    }
}
Run Code Online (Sandbox Code Playgroud)

非常感谢您抽出时间。

Jor*_*ann 5

根据文档,您可以使用与定义索引复合键相同的方括号语法为表定义复合主键:

db.version(1).stores({
  items: '[name+date]'
});
Run Code Online (Sandbox Code Playgroud)

这将产生一个 IndexedDB 表Key (Key path: ["name", "date"])


Table接口的 Dexie TypeScript 定义将Key泛型定义为any

interface Table<T=any,Key=any> extends _Table<T,Key> {}
Run Code Online (Sandbox Code Playgroud)

允许您传递类型数组作为Key声明Table

Dexie.Table<IItem, [string, Date]>;
Run Code Online (Sandbox Code Playgroud)

name您可以通过将和date作为值数组传递给函数来查询化合物 PK,其get顺序与定义化合物 PK 的顺序相同[name+date]

db.items.get([anItemName, aDate])
Run Code Online (Sandbox Code Playgroud)

下面是一个工作示例。

作为参考,该示例匹配的 IndexedDB 键路径如下所示:

["widget", Sat Dec 12 2020 09:00:00 GMT-0500 (Eastern Standard Time)]
Run Code Online (Sandbox Code Playgroud)

生成的控制台日志如下所示:

{name: "widget", date: "2020-12-12T14:00:00.000Z", description: "widget_2", value: 20}
Run Code Online (Sandbox Code Playgroud)
import Dexie from "dexie";

interface IItem {
  name?: string;
  date?: Date;
  description?: string;
  value?: number;
}

class ItemDatabase extends Dexie {
  items: Dexie.Table<IItem, [string, Date]>; // <<<

  constructor() {
    super("SO_64210806");
    this.version(1).stores({
      items: "[name+date]" // <<<
    });
  }
}

(async () => {
  const db = new ItemDatabase();

  await db.items.bulkPut([
    {
      name: "widget",
      date: new Date("2020-12-11T13:00:00.000Z"),
      description: "widget_1",
      value: 10
    },
    {
      name: "widget",
      date: new Date("2020-12-12T14:00:00.000Z"),
      description: "widget_2",
      value: 20
    }
  ]);

  const w2 = await db.items.get(["widget", new Date("2020-12-12T14:00:00.000Z")]); // <<<

  console.log(w2);
})();
Run Code Online (Sandbox Code Playgroud)