我很欣赏数据库表中NULL值的语义含义,不同于false和空字符串''.但是,当字段可以为空时,我经常阅读有关性能问题的内容,并建议在NULL实际上在语义上正确的情况下使用空字符串.
什么情况适合使用可空字段和NULL值?有什么权衡取舍?简单地避免完全使用NULL并简单地使用空字符串,false或0表示缺少值是明智的吗?
UPDATE
好的 - 我理解'和NULL之间的语义差异以及NULL是适当的字段值的(性能不可知)情况.但是,让我扩展一下暗示的性能问题.这是来自Schwartz,Zeitsev等人的优秀"高性能MySQL" http://www.borders.co.uk/book/high-performance-mysql-optimization-backups-replication-and-more/857673/:
MySQL更难以优化引用可空库存的查询,因为它们使索引,索引统计和值比较更加复杂.可空列使用更多存储空间,并且需要在MySQL内部进行特殊处理.当索引可空列时,每个条目需要一个额外的字节,甚至可以在MyISAM中将固定大小的inded(例如单个整数列上的索引)转换为可变大小的列.
更多信息: Google图书预览
这很可能是明确的答案 - 我只是在寻找前线的第二意见和经验.
但是,当字段可以为空时,我经常阅读有关性能问题的内容,并建议在NULL实际上在语义上正确的情况下使用空字符串.
我会在一段时间内对词语选择不屑一顾:
即使它是一个重要的性能因素,使用值而不是NULL 也不会使它在语义上正确.在SQL中,NULL具有语义角色,表示缺少或不适用的值.给定RDBMS实现中NULL的性能特征与此无关.性能可能因品牌或版本而异,但语言中NULL的目的是一致的.
在任何情况下,我都没有听说有任何证据表明NULL表现不佳.我对任何对性能测量的引用感兴趣,这些性能测量显示可空列的性能比不可空列更差.
我并不是说我没有错,或者在某些情况下它不可能是真的 - 只是假设空闲假设没有意义.科学不是由猜想构成的; 一个人必须显示可重复测量的证据.
指标还告诉您多少的性能不同,这样你就可以做出是否东西可以值得担心的判决.也就是说,影响可以是可测量的非零,但与更高的性能因素相比仍然无关紧要,例如正确索引表或调整数据库缓存大小.
在MySQL中,搜索NULL可以从索引中受益:
mysql> CREATE TABLE foo ( i INT NOT NULL, j INT DEFAULT NULL, PRIMARY KEY (i), UNIQUE KEY j_index (j) ); mysql> INSERT INTO foo (i, j) VALUES (1, 1), (2, 2), (3, NULL), (4, NULL), (5, 5); mysql> EXPLAIN SELECT * FROM foo WHERE i = 3; +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | foo | const | PRIMARY | PRIMARY | 4 | const | 1 | | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ mysql> EXPLAIN SELECT * FROM foo WHERE j IS NULL; +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+ | 1 | SIMPLE | foo | ref | j_index | j_index | 5 | const | 2 | Using where | +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
请注意,这仍然不是性能的衡量标准.我只显示你可以在搜索NULL时使用索引.我将断言(诚然没有测量,但嘿,这只是StackOverflow)索引的好处掩盖了搜索NULL与空字符串时的任何可能的惩罚.
选择零或空白或任何其他值来替换NULL不是正确的设计决策.您可能需要在列中使用这些值作为重要值.这就是为什么NULL存在,作为一个值,根据定义在任何数据类型的值域之外,因此您可以使用整数范围的整数或字符串或其他值,并且仍然有一些东西表示"没有上述值. "
MySQL手册实际上有一篇关于NULL问题的好文章.
希望能帮助到你.
还找到了关于NULL和Performance的其他SO帖子
我们不允许在数据库中使用NULL值,除非它是数值或日期.我们这样做的原因是因为数值有时不应该默认为零,因为这非常非常糟糕.我是股票经纪人的开发人员,而且NULL和0之间存在很大的差异.如果我们确实希望将默认值恢复为零,那么使用COALESCE会派上用场,即使我们不这样存储它们也是如此.
MyVal = COALESCE(TheData, 0)
当我们从平面文件中批量插入数据时,我们使用格式文件来确定数据的输入,无论如何都会自动将空值转换为空白字符串.
日期默认为可能出现的任何值依赖于我认为的整理,但我们的默认值类似于1900,而且日期非常重要.其他纯文本值并不那么重要,如果留空则通常符合条件.