添加一个布尔字段vs检查字段是否为非空?

时间:2017-06-20 15:03:40

标签: mysql database database-design

在记录公开可见之前,我们使用需要管理员批准记录的表格。我想知道最合适的方法是设计这样一个表,其中主要查询是检索已批准(或尚未批准)的记录。

假设查询的列将被编入索引:

  1. 使用布尔字段有什么速度优势吗?
  2. 检查列是否为NULL违反最佳做法?
  3. 例如:

    id | title | text | approved_dttm
    ---------------------------------------
    1  | ...   | ...  | null 
    2  | ...   | ...  | 2017-01-01 00:00:00 ETC
    
    
    SELECT * FROM table where approved_dttm IS NOT NULL; 
    

    VS

    id | title | text | approved | approved_dttm
    ---------------------------------------
    1  | ...   | ...  | 0        | null 
    2  | ...   | ...  | 1        | 2017-01-01 00:00:00 ETC
    
    
    SELECT * FROM table where approved = 1; 
    

    注意:除批准/未批准外,我们不需要多个州。没有“需要进一步审查”等。

2 个答案:

答案 0 :(得分:0)

1)添加approved字段只会复制可以从approved_dttm派生的信息,因此从信息的角度来看,没有必要添加它。

2)从索引的角度来看,您可能会认为布尔(well,tinyint)字段的索引小于索引日期时间字段。但是,这个索引的选择性很低(只有2个可能的值),因此MySQL在实际选择数据时很可能会忽略这样的索引。

总而言之,我不会添加额外的布尔字段来指示条目是否被批准。

答案 1 :(得分:0)

问:使用布尔字段有什么速度优势吗?

答:没有。

在这种情况下,任何查询都不太可能获得速度效益"使用approved列与approved_dttm IS [NOT] NULL

虽然批准列的附加字节可以忽略不计(假设它被定义为TINYINT,但该额外字节不会真正影响"适合"在一个块中的行数)。该列上的索引不可忽略不计。这将需要额外的块(空间),并且会增加维护索引条目的开销。

我们不能排除一些特殊的角落案例,其中添加该列会有所帮助,但一般而言,鉴于提供的信息,不,没有"速度优势&#34 ;添加该列。

(我们在这里留下了冗余数据和更新异常的讨论...添加(冗余)approved列,面对第三范式,以及熟悉的口头禅&# 34;每个属性都取决于密钥,整个密钥,只有密钥。所以请帮助我Codd"。)

问:检查列是否为NULL违反最佳做法?

答:没有。

它不违反任何"最佳做法"我知道。 NULL和三值布尔逻辑已经永远存在(自从EFCodd第一次创造"关系" 1970年,1977年系统/ R和Oracle的出现,以及1983年的DB2,。 ..)

某些应用程序开发人员可能不喜欢(或理解)如何处理NULL值的细微差别。确定将列定义为NOT NULL可能会减轻他们的负担。但在我的书中,"避免处理NULL"是不是 a"最佳做法"。

我们注意到有一些数据库实现的怪癖,没有使用索引来满足col IS NULL谓词。但是这些怪癖通常会通过适当定义的索引和仔细编写的查询来克服。理解NULL值及其怪癖并处理它 a"最佳实践"。