代码之家  ›  专栏  ›  技术社区  ›  TKoL

德克西。js自动增量主键-是否重置过?如何重置?

  •  1
  • TKoL  · 技术社区  · 6 年前

    在德西。js您可以使用自动递增键创建存储

        let db = new Dexie("nav_api");
        db.version(1).stores({
            jobs: '++id, json'
        });
    

    为了测试,我通过在db中创建了14个对象 db.jobs.put({json: '[]'}) ,他们所有的钥匙都按预期出来了,从1点到14点。然后删除了后来的一些, db.jobs.where('id').above(6).delete() ,并将另一个添加到数据库中,其索引为15。

    有没有办法将索引重置为0?我用它来排序,我不确定当值变得非常大时会发生什么——它最终会回到0吗?

    另一方面,这也可能不是我需要担心的事情。根据“++id”字段的高度,我假设它将达到数十亿,这将需要很多年(很多生命期)才能让人担心。所以也许我应该忽略它。

    [编辑] 我试着清理桌子, db.jobs.clear() 然后在表中放入新行,但它再次使用后面的下一个索引。我找不到完全删除表的方法,但是我可以完全删除整个数据库,但我真的不想这样做。

    2 回复  |  直到 6 年前
        1
  •  2
  •   dumbmatter    6 年前

    The IndexedDB spec has more info.

    你可能不会达到上限:

    当前数字始终是小于或等于2的正整数 53 (9007199254740992)+1。

    除了删除对象存储并重新创建它之外,无法重置它:

    密钥生成器的当前编号永远不会减少,除非数据库操作被还原。从对象存储中删除记录不会影响对象存储密钥生成器。即使清除对象存储区中的所有记录,例如使用clear()方法,也不会影响对象存储区键生成器的当前数目。

        2
  •  0
  •   Pandora    6 年前

    公认的答案只是部分解决了问题,并没有以代码的形式提供问题的实际解决方案。在我看来,不需要计算自动递增的整数不是一个好主意。当然,一个人需要大量的数据,但高数字可能会激怒用户,尤其是当他们问自己之前的id在哪里时。

    我主要是抄过来的 this script 来自Dexie开发者 dfahlander公司 并对其进行了修改以达到要求。请注意,来回克隆数据库可能需要很长时间才能运行,具体取决于数据库的大小。bulkAdd没有包装在事务中,因此脚本可能会出现错误。 也就是说,我必须警告您在执行此功能之前进行备份。

    function refreshIndices(database){
    
      const databases = [database, database+'_temp'];
      // Loop 2 times - move database forth and back
      (function next(cnt, max){
        if(cnt++ >= max){ doSomething(); return;}
        // ! turns 1 into 0 and vice-versa / + turns boolean into integer
        var sdb = new Dexie(databases[cnt-1]),
            ddb = new Dexie(databases[+!(cnt-1)]);
    
        sdb.open().then(()=>{
            // Clone scheme
            const schema = sdb.tables.reduce((result,table)=>{
              result[table.name] = (
                [table.schema.primKey]
                .concat(table.schema.indexes)
                .map(indexSpec => indexSpec.src)
                ).toString();
              return result;
            }, {});
            ddb.version(sdb.verno).stores(schema);
    
            // Clone Data and delete source-database
            return sdb.tables.reduce(
              (result, table) => result
                .then(() => table.toArray())
                .then(rows => ddb.table(table.name).bulkAdd(rows) ),
              Promise.resolve()     
            ).then((x)=>{ sdb.delete(); ddb.close(); next(cnt,max); })
        })
      })(0, databases.length);
    }
    

    必须使用要克隆的字符串形式的数据库名称调用此函数。(即。 refreshIndices('dbname') )数据库必须存在。该函数迭代2次。在第一次运行时,将源数据库克隆到临时数据库中,然后删除源数据库。完成后,该函数将再次运行并将临时数据库克隆到源数据库中,然后删除临时数据库。不会留下任何开销。

    出于调试目的,我会更改

    .then(rows => ddb.table(table.name).bulkAdd(rows) )
    

    .then((rows) => { 
        console.log("Cloning "+table.name);
        ddb.table(table.name).bulkAdd(rows)
    }) )
    

    这个功能应该可以在Dexie的支持下使用。js。还可以通过以下方式创建数据库 Developer Tools (Chrome) => Application => IndexedDB => __dbnames => Refresh