我同意@RickJames 关于 NULL 的看法。不要在你的意思是使用像true 这样的真实值的地方使用NULL。同样,不要使用像 0 或 '' 这样的实际值来表示没有值。
至于性能影响,您应该知道要搜索 NULL 的存在/不存在,您将使用谓词 is_archive IS [NOT] NULL。
如果您在查询中使用 EXPLAIN,您会看到该谓词算作“范围”访问类型。而搜索单个特定值,例如is_archive = 1 或 is_archive = 0 是“ref”访问类型。
这将对某些查询产生性能影响。例如,如果您在 (is_archived, created_on) 上有一个索引,并且您尝试执行如下查询:
SELECT ... FROM roles
WHERE is_archived IS NULL AND created_on = '2017-01-31'
那么索引将只有一半的用处。 WHERE 子句无法搜索索引中的第二列。
但如果你使用真实值,那么查询如下:
SELECT ... FROM roles
WHERE is_archived = 0 AND created_on = '2017-01-31'
将使用索引中的两列。
关于 NULL 存储的评论:
是的,在 InnoDB 存储引擎中,内部每行存储一个位域,每列 1 位,其中位指示每列是否为 NULL。这些位存储紧凑,即一个字节最多包含 8 个位。位域之后是一系列列值。为 NULL 的列不存储任何值。所以是的,从技术上讲,使用 NULL 确实可以减少存储空间。
但是,当您的意思是 false 时,我敦促您简化数据管理并使用 false。不要将 NULL 用于您的值之一。如果您以每行保存一个字节很重要的规模管理数据,我想会有一个例外。例如,如果您要管理数百亿行。
但在比这更小的规模上,潜在的空间节省不值得您为项目增加额外的复杂性。
从角度来看,InnoDB 页面无论如何只会填充每个数据页面 15/16。因此,InnoDB 页面格式的开销可能大于您从微优化布尔存储中获得的节省。