这是Sqlite中唯一索引的正常行为吗?

时间:2014-03-28 01:14:21

标签: sqlite indexing

我在Flash中使用SQLite。 我有这个独特的索引:

CREATE UNIQUE INDEX songsIndex ON songs ( DiscID, Artist, Title )

我设置了一个参数化的递归函数来插入任何新行(单个或多个)。

如果我尝试插入一个具有相同DiscID,艺术家和标题的行作为现有行,它可以正常工作 - 即它忽略插入现有行,并告诉我1个记录中的0个已更新 - 好。

但是,例如,如果DiscId为空白,但艺术家和标题不是,则当已经有一个空白DiscId并且具有相同的艺术家和标题时,会创建一个新记录 - BAD。

我在插入之前追踪了光盘ID,Flash告诉我它未定义。因此,我已将其编码为将未定义的内容设置为"" (一个空字符串),以确保它真正插入一个空字符串 - 但后续插入仍然会忽略唯一索引并添加一个全新的行,即使存在相同的行。

我误解了什么?

感谢您的时间和帮助。

2 个答案:

答案 0 :(得分:1)

SQLite允许NULL个字段参与UNIQUE索引。如果您有这样的索引,并且如果您添加记录使得三列中的两列具有相同的值而另一列在两个记录中都为NULL,则SQLite将允许该匹配您正在看到的行为。

因此,最可能的解释是,尽管您努力使用INSERT零长度字符串,但实际上您仍然INSERT NULL s。

此外,除非您在OR IGNORE语句中明确包含INSERT,否则当您尝试将重复的INDEX值插入到SQLite中时,SQLite的预期行为是抛出错误UNIQUE INDEX。由于你没有看到这种行为,我猜测Flash提供了某种围绕SQLite的包装器,它隐藏了你的真实行为(也可能是将空字符串转换为NULL)。

答案 1 :(得分:0)

拉里的答案很好。对于遇到相同问题的任何人,这里都是SQLite文档的引文,解释为在这种情况下,所有NULL都被视为不同值:

出于唯一索引的目的,将考虑所有NULL值 与所有其他NULL值不同,因此是唯一的。这是一 SQL-92标准的两种可能解释( 语言中的语言是不明确的)。使用的解释 SQLite是相同的,并且是PostgreSQL遵循的解释, MySQL,Firebird和Oracle。 Informix和Microsoft SQL Server紧随其后 标准的另一种解释,那就是所有NULL 值彼此相等。

查看此处:https://www.sqlite.org/lang_createindex.html