我还是比较陌生的数据库设计,我正在用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代替“最佳做法”?我认为这总是最好的做法,但现在我认为它可能永远不是最好的做法。
答案 0 :(得分:2)
NULL
和空字符串在语义上不同,就像NULL
和0
在语义上不同。
NULL
表示“没有价值”。在你的情况下,这将是“没有地址”。
空字符串是零字符串的字符串字符串值。在您的情况下,这将是一个空字符串的地址。
是否使用NULL
或空字符串取决于情境的语义,就像决定是使用NULL
还是0
一样。强>
但是,NULL
在比较,IN
,索引,DISTINCT
和GROUP 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你会问这个陈述。
最佳做法是根据您的意思做出决定:没有价值,或没有字符的价值。 (当然,您可能总是出于个人原因选择放弃最佳实践。)