【问题标题】:Boolean vs tinyint(1) for boolean values in MySQLBoolean vs tinyint(1) 用于 MySQL 中的布尔值
【发布时间】:2011-04-14 16:34:18
【问题描述】:

什么列类型最适合在 MySQL 数据库中用于布尔值?我使用boolean,但我的同事使用tinyint(1)

【问题讨论】:

  • 似乎MySQL透明地将boolean视为tinyint(1)。所以你可以使用booleantruefalse,MySQL将它们视为tinyint(1)10
  • 另一种情况是带有 Y & N 的字符 1,这对某些人来说应该更快。

标签: sql mysql


【解决方案1】:

这些数据类型是同义词。

【讨论】:

  • 我不会说数据 types 是同义词—— tinyint(1) 与 bool 相同,但 tinyint 和 bool 不同。小问题,但你的回答在我第一次阅读时让我绊倒了
  • 这不能回答问题。虽然 tinyint(1) 确实在功能上与 bool 相同,但 OP 询问最好使用什么。 @dj_segfault 的答案很好地解释了为什么在存储布尔值时 bool 应该优于 tinyint(1)。
【解决方案2】:

我将在这里采取不同的方法,并建议您的开发人员理解您的代码与编译器/数据库理解代码一样重要。使用 boolean 可能与使用 tinyint 做同样的事情,但它的优点是语义传达了您的意图,这是值得的。

如果您使用tinyint,您应该看到的唯一值不是很明显01
boolean 总是 truefalse

【讨论】:

    【解决方案3】:

    boolean 在 MySQL 中不是一个独特的数据类型;它只是tinyint 的同义词。 See this page in the MySQL manual。 请参阅下面来自dev.mysql.com/doc/的引用和示例

    BOOL, BOOLEAN 这些类型是 TINYINT(1) 的同义词。零值 被认为是错误的。非零值被认为是真的:

        mysql> SELECT IF(0, 'true', 'false');
        +------------------------+
        | IF(0, 'true', 'false') |
        +------------------------+
        | false                  |
        +------------------------+
        mysql> SELECT IF(1, 'true', 'false');
        +------------------------+
        | IF(1, 'true', 'false') |
        +------------------------+
        | true                   |
        +------------------------+
        mysql> SELECT IF(2, 'true', 'false');
        +------------------------+
        | IF(2, 'true', 'false') |
        +------------------------+
        | true                   |
        +------------------------+
    

    但是,TRUE 和 FALSE 值分别只是 1 和 0 的别名,如下所示:

    mysql> SELECT IF(0 = FALSE, 'true', 'false');
    +--------------------------------+
    | IF(0 = FALSE, 'true', 'false') |
    +--------------------------------+
    | true                           |
    +--------------------------------+
    mysql> SELECT IF(1 = TRUE, 'true', 'false');
    +-------------------------------+
    | IF(1 = TRUE, 'true', 'false') |
    +-------------------------------+
    | true                          |
    +-------------------------------+
    mysql> SELECT IF(2 = TRUE, 'true', 'false');
    +-------------------------------+
    | IF(2 = TRUE, 'true', 'false') |
    +-------------------------------+
    | false                         |
    +-------------------------------+
    mysql> SELECT IF(2 = FALSE, 'true', 'false');
    +--------------------------------+
    | IF(2 = FALSE, 'true', 'false') |
    +--------------------------------+
    | false                          |
    +--------------------------------+
    

    最后两个语句显示显示的结果,因为 2 等于 既不是 1 也不是 0。

    我个人建议使用 tinyint 作为首选项,因为 boolean 不会像您从名称中认为的那样做,因此它会产生潜在的误导性代码。但在实际层面上,这并不重要——它们都做同样的事情,所以你不会通过使用任何一个来获得或失去任何东西。

    【讨论】:

    • 虽然这是一个非常彻底的回应,但最后您还是分享了您对tinyint 的偏好,并指出“布尔值不会像您从名称中认为的那样做”。你能详细说明吗?我发现这个答案非常好(stackoverflow.com/a/47404140/2099911):“...(boolean)带有你正在尝试做的事情的语义”。
    【解决方案4】:

    使用 enum 简单快捷

    我不推荐 enum 或 tinyint(1),因为 bit(1) 只需要 1 位来存储布尔值,而 tinyint(1) 需要 8 位。

    参考

    TINYINT vs ENUM(0, 1) for boolean values in MySQL

    【讨论】:

    • 我们不能使用枚举,因为我们的数据库也需要支持sqlite
    • 如果你使用 InnoDB,bit 最终会使用和 tinyint 一样多的空间。来自High Performance MySQL(percona 家伙)“InnoDB 将每个 [bit] 列存储为足够大以包含位的最小整数类型,因此您不会节省任何存储空间。”唯一的好处是如果您在 BIT(morethan1) 列中存储多个布尔值。因此,如果您只有一个布尔字段,则使用 tinyint 与 InnoDB 中的 bit 相同,并且更可取,因为 tinyint 通常更易于使用。
    • 不适用于 MySQL:BIT(M) - approximately (M+7)/8 bytes 请参阅:dev.mysql.com/doc/refman/8.0/en/storage-requirements.html
    【解决方案5】:

    虽然booltinyint(1) 确实在功能上 相同,但bool 应该是首选选项,因为它包含您正在尝试执行的操作的语义含义。此外,许多 ORM 会将 bool 转换为您的编程语言的本机布尔类型。

    【讨论】:

      【解决方案6】:

      我使用 Dapper 连接到 MySQL 的经验是它确实很重要。我使用以下脚本将不可为空的 bit(1) 更改为可空的 tinyint(1):

      ALTER TABLE TableName MODIFY Setting BOOLEAN null;
      

      然后 Dapper 开始抛出异常。我试图查看脚本前后的差异。并注意到 bit(1) 已更改为 tinyint(1)。

      然后我跑了:

      ALTER TABLE TableName CHANGE COLUMN Setting Setting BIT(1) NULL DEFAULT NULL;
      

      这解决了问题。

      【讨论】:

        【解决方案7】:

        当您选择 int 或 bool 时,这很重要,尤其是当可空列发挥作用时。

        想象一个包含多张照片的产品。你怎么知道哪张照片是产品封面?好吧,我们将使用一个列来指示它。

        到目前为止,product_image 表有两列:product_idis_cover

        酷吗?还没有。由于产品只能有一个封面,我们需要在这两列上添加唯一索引。

        但是等等,如果这两列将获得唯一索引,您将如何存储同一产品的许多非封面图像?唯一索引会在这里抛出错误。

        所以你可能虽然“好的,但是你可以使用 NULL 值,因为这些值被唯一索引检查所忽略”,是的,这是事实,但我们在这里失去了语言规则。

        布尔类型列中NULL值的作用是什么?是“全部”、“任何”还是“否”? boolean 列中的 null 值允许我们使用唯一索引,但它也弄乱了我们解释记录的方式。

        我会说,在某些情况下,整数可以起到更好的作用,因为它不受严格的真假含义的约束

        【讨论】:

          猜你喜欢
          • 2011-11-25
          • 2012-10-18
          • 2011-05-23
          • 1970-01-01
          • 1970-01-01
          • 2020-02-03
          • 1970-01-01
          • 2017-03-27
          • 1970-01-01
          相关资源
          最近更新 更多