我使用带有自动递增ID和邮件地址的表Mail
。该表用于其他4个表中,主要用于保存存储空间(String只保存一次而不是4次)。我使用INSERT OR IGNORE
只是盲目地将邮件地址添加到表中,如果存在则忽略更新。这种方法比使用SELECT ...
检查存在要快得多,并在需要时执行INSERT
。
对于每个INSERT OR IGNORE
自动递增,无论是否被忽略或完成,自动递增Id都会递增。我跑了一次我约。 500k数据集继续进行。因此,每次运行后,最后一个自动增量键增加500k。我知道有2 ^ 63-1个可能的键,所以很长时间才能使用它们。
我也试过了INSERT OR REPLACE
,但这会在每次运行命令时增加数据集的Id,所以这根本不是解决方案。
有没有办法阻止每个INSERT OR IGNORE
增加自动增量键?
mIdMail mMail
"1" ""
"7" "mail1@example.com"
"15" "mail2@example.com"
"17" "mail3@example.com"
"19" "mail4@example.com"
"23" "mail5@example.com"
...
插入查询(使用Java Lib:org.apache.commons.dbutils)
INSERT OR IGNORE
INTO MAIL
( mMail )
VALUES ( ? );
表定义
CREATE TABLE IF NOT EXISTS MAIL (
mIdMail INTEGER PRIMARY KEY AUTOINCREMENT,
mMail CHAR(90) UNIQUE
);
答案 0 :(得分:3)
要获得无间隙的自动增量值,请删除AUTOINCREMENT关键字。 (是的,你get autoincrementing values even without it。)
答案 1 :(得分:1)
自动增量键的行为与它们的具体行为相同,因为数据库保证了它们的行为 - 无论并发事务和事务失败。
自动增量键有两个保证:
分配密钥的机制并不能保证没有间隙。为什么不?因为无间隙会在数据库上产生更多的开销。基本上,表上的每个事务都需要在下一个事务发生之前完全序列化(完成并提交)。一般来说,从绩效角度来看,这是一个非常糟糕的主意。
不幸的是,SQLite没有最简单的解决方案,只需在自动递增的密钥上调用row_number()
即可。您可以尝试使用触发器实现无间隙自动增量,从而显着降低应用程序的速度。
我真正的建议只是忍受差距。接受他们。投降。这就是内置方法的工作方式,并且有充分的理由。现在设计数据库/应用程序的其余部分,牢记这一点。