在检查唯一时,我应该使用空字符串而不是NULL吗?

时间:2013-11-17 07:12:07

标签: sql sqlite

我还是比较陌生的数据库设计,我正在用SQLite创建一个表。我以为我被教导说最好用NULL代替空字符串,这就是我一直在做的事情。我正在使用以下行构建地址表:

CREATE TABLE addresses (
addressID INTEGER PRIMARY KEY, 
officeName TEXT,
address TEXT NOT NULL CHECK(address<>''),
UNIQUE (officeName, address)

使用行

向数据库添加地址(通过PHP PDO)
INSERT OR IGNORE INTO addresses (officeName,address) VALUES (?,?)

该行应该检查officeName /地址是否已经在数据库中,如果是,则忽略它,如果不存在则添加它。 “Address”始终是非空字符串,但有时officeName为空。如果我将其设为NULL,它会不断添加,好像每个NULL都是不同的(如果它只是一个空字符串,它就可以正常工作)。我确实发现this article说是,NULL在唯一列中被视为不同。现在让我想知道......我应该总是只使用空字符串而不是NULL吗?有没有一种情况下使用NULL代替“最佳做法”?我认为这总是最好的做法,但现在我认为它可能永远不是最好的做法。

1 个答案:

答案 0 :(得分:2)

NULL和空字符串在语义上不同,就像NULL0在语义上不同。

NULL表示“没有价值”。在你的情况下,这将是“没有地址”。

空字符串是零字符串的字符串字符串值。在您的情况下,这将是一个空字符串的地址。

是否使用NULL或空字符串取决于情境的语义,就像决定是使用NULL还是0一样。

但是,NULL在比较,IN,索引,DISTINCTGROUP BY方面有点混乱。 Everyone seems to do things a little differently(仅供参考,此链接不包括SQL Server,它以另一种方式执行),所以不幸的是,通常会做出妥协以适应特定的期望行为,具体取决于DBMS。

在您的情况下,如果您想使用您感兴趣的SQLite功能,则必须使用空字符串。

  

SQLite最初的编码方式是[NULL永远不会分开]。但是实验运行了   在其他SQL引擎上显示它们都没有这样工作。所以   SQLite被修改为与Oracle,PostgreSQL和DB2一样工作。   这涉及为了SELECT的目的使NULL不明显   DISTINCT语句和SELECT中的UNION运算符。 NULL是   在UNIQUE专栏中仍然有所不同。这似乎有点武断,但是   与其他发动机兼容的愿望超过了这一点   异议。

但是,要知道INSERT OR IGNORE是SQLite独有的;因为没有其他DBMS你会问这个陈述。

最佳做法是根据您的意思做出决定:没有价值,或没有字符的价值。 (当然,您可能总是出于个人原因选择放弃最佳实践。)