Dexie.js 自动增量主键 - 它曾经重置过吗?如何重置?
Dexie.js Autoincrement Primary Key - does it ever reset? How to reset it?
在 Dexie.js 中,您可以创建一个带有自动递增键的商店
let db = new Dexie("nav_api");
db.version(1).stores({
jobs: '++id, json'
});
所以为了测试,我通过 db.jobs.put({json: '[]'})
在数据库中创建了 14 个对象,它们的所有键都按预期出现,从 1 开始到 14。然后删除了一些后面的,db.jobs.where('id').above(6).delete()
,又在数据库中添加了一个,索引为15.
有什么方法可以将索引重置为0吗?我用它来订购,但我不确定当值变得非常大时会发生什么——它最终会回到 0 吗?
另一方面,这可能也不是我需要担心的事情。取决于“++id”字段的高度,我假设它将达到数十亿,这将是许多年(许多世)之后才值得担心的事情。所以也许我应该忽略它。
[编辑]
我尝试清除 table、db.jobs.clear()
,然后在 table 中放入一个新行,但它再次使用了下一个索引。我找不到完全删除 table 的方法,但是我可以完全删除整个数据库,但我真的不想那样做。
The IndexedDB spec has more info.
你可能达不到上限:
The current number is always a positive integer less than or equal to 253 (9007199254740992) + 1.
除了删除对象存储并重新创建之外,没有办法重置它:
The current number for a key generator never decreases, other than as a result of database operations being reverted. Deleting a record from an object store never affects the object store’s key generator. Even clearing all records from an object store, for example using the clear() method, does not affect the current number of the object store’s key generator.
接受的答案仅部分解决了问题,并未以代码形式提供问题的实际解决方案。在我看来,在不需要的情况下计算自动递增的整数不是一个好主意。肯定会需要大量数据,但大量数据可能会激怒用户,尤其是当他们问自己以前的 ID 在哪里时。
我主要从 Dexie-Developer 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 次。首先 运行,源数据库被克隆到一个临时数据库中,然后源数据库被删除。完成后,函数 运行s 再次将临时数据库克隆到源数据库中,然后删除临时数据库。不会留下任何开销。
出于调试目的,我会更改
.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
.
在 Dexie.js 中,您可以创建一个带有自动递增键的商店
let db = new Dexie("nav_api");
db.version(1).stores({
jobs: '++id, json'
});
所以为了测试,我通过 db.jobs.put({json: '[]'})
在数据库中创建了 14 个对象,它们的所有键都按预期出现,从 1 开始到 14。然后删除了一些后面的,db.jobs.where('id').above(6).delete()
,又在数据库中添加了一个,索引为15.
有什么方法可以将索引重置为0吗?我用它来订购,但我不确定当值变得非常大时会发生什么——它最终会回到 0 吗?
另一方面,这可能也不是我需要担心的事情。取决于“++id”字段的高度,我假设它将达到数十亿,这将是许多年(许多世)之后才值得担心的事情。所以也许我应该忽略它。
[编辑]
我尝试清除 table、db.jobs.clear()
,然后在 table 中放入一个新行,但它再次使用了下一个索引。我找不到完全删除 table 的方法,但是我可以完全删除整个数据库,但我真的不想那样做。
The IndexedDB spec has more info.
你可能达不到上限:
The current number is always a positive integer less than or equal to 253 (9007199254740992) + 1.
除了删除对象存储并重新创建之外,没有办法重置它:
The current number for a key generator never decreases, other than as a result of database operations being reverted. Deleting a record from an object store never affects the object store’s key generator. Even clearing all records from an object store, for example using the clear() method, does not affect the current number of the object store’s key generator.
接受的答案仅部分解决了问题,并未以代码形式提供问题的实际解决方案。在我看来,在不需要的情况下计算自动递增的整数不是一个好主意。肯定会需要大量数据,但大量数据可能会激怒用户,尤其是当他们问自己以前的 ID 在哪里时。
我主要从 Dexie-Developer dfahlander 复制
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 次。首先 运行,源数据库被克隆到一个临时数据库中,然后源数据库被删除。完成后,函数 运行s 再次将临时数据库克隆到源数据库中,然后删除临时数据库。不会留下任何开销。
出于调试目的,我会更改
.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
.