在这种特定情况下,在MySql Structure中使用NULL的优缺点是什么?

时间:2017-01-31 07:26:06

标签: mysql indexing storage

我有一个如下所示的表结构包含我所采用的角色结构:

enter image description here

让它成为"角色"表包含一些与用户角色相关的记录。 现在我在这里采取了一个列#34; is_archived(int)"我用它来了解该角色仍然存在或删除。

所以我正在考虑该列的两个值:

  • " NULL" = GT;如果该角色仍然存在(如TRUE),
  • " 1" =>如果删除/不活动(如FALSE)

对于我的表,最大记录将包含" NULL"此列的值和默认值也是" NULL"。

现在我处于两难境地,因为我正在使用" NULL"而不是" 0"。

我需要知道这种情况的利弊(例如"搜索性能","存储","索引"等)。

如果有利弊,最好的选择是什么?

2 个答案:

答案 0 :(得分:1)

我的观点是NULL用于“带外”,而不是用于克服带内值。如果存在性能或空间差异,则无关紧要。

对于true / false,请使用TINYINT NOT NULL。它只有1个字节。你可以使用ENUM('false', 'true');它也是1个字节。

INT,无论后面的数字是多少,都需要4个字节。不要将INT用于这种低基数的事情。

NULL表示“尚未知晓”或您还不能说“真实”或“错误”的任何其他情况。 (因为你可能总是知道它是否已'存档',NULL在这里没有位置。

甚至可以使用ENUM('male', 'female', 'decline_to_state', 'transgender', 'gay', 'lesbian', 'identifies_as_male', 'North_Carolina_resident', 'other')。 (警告:这只是一个部分列表;最好设置一个表格并JOIN。)

答案 1 :(得分:0)

我同意@RickJames关于NULL。如果您想使用像true这样的实际值,请不要使用NULL。同样,不要使用像0或''这样的实际值来表示没有值。

至于性能影响,您应该知道要搜索NULL的存在/不存在,您将使用谓词is_archive IS [NOT] NULL

如果对查询使用EXPLAIN,您将看到该谓词计为“范围”访问类型。而搜索单个特定值,例如, is_archive = 1is_archive = 0是“参考”访问类型。

这会对某些查询产生性能影响。例如,如果你有一个索引(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页面格式的开销可能比微优化布尔存储所节省的成本更高。