代码之家  ›  专栏  ›  技术社区  ›  Devner

哪个更快:char(1)或tinyint(1)?为什么?

  •  25
  • Devner  · 技术社区  · 15 年前

    我的平台:

    PHP与MySQL

    我的处境:

    我遇到了一种情况,需要在表的某一列中存储用户选择的值。现在我的选择是:

    1. 将列声明为char(1),并将值存储为“y”或“n”
    2. 或将列声明为tinyint(1),并将值存储为1或0
    3. 如此声明的此列也可以编入索引以便在应用程序中使用。

    我的问题:

    所以我想知道上面两种类型中的哪一种:

    1. 当访问该列时,会导致更快的查询速度(为了简单起见,请不要混合其他查询或访问其他列)。

    2. 存储和访问数据的最有效方法是什么?为什么?

    3. 如果列是索引的,而当列不是索引的时候,访问速度如何变化?

    我的理解是,由于char(1)和tinyint(1)只占用1字节的空间,因此在这种情况下,存储空间不会成为问题。那么剩下的就是访问速度。据我所知,数字索引比其他任何索引都更快、更有效。 但我认为这件事很难决定。很想听听你在这方面的经验。

    提前谢谢。

    8 回复  |  直到 8 年前
        1
  •  30
  •   Ivan Nevostruev    15 年前

    我认为你应该用 ENUM('n','y') . MySQL以最佳方式存储这种类型。它还将帮助您在字段中只存储允许的值。

    你也可以让它更人性化 ENUM('no','yes') 不影响性能。因为字符串 'no' 'yes' 每只存储一次 ENUM 定义。MySQL只存储每行值的索引。

    还要注意排序依据 枚举 专栏:

    枚举值根据列规范中列出枚举成员的顺序进行排序。(换句话说,枚举值是根据其索引编号排序的。)例如,“a”在“b”之前排序表示枚举(“a”、“b”),而“b”在“a”之前排序表示枚举(“b”、“a”)。

        2
  •  36
  •   Glen Solsberry    15 年前
                           Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
    insert tinyint(1)     207/s                --            -1%                  -20%
    insert char(1)        210/s                1%             --                  -19%
    insert enum('y', 'n') 259/s               25%            23%                    --
                           Rate insert char(1) insert tinyint(1) insert enum('y', 'n')
    insert char(1)        221/s             --               -1%                  -13%
    insert tinyint(1)     222/s             1%                --                  -13%
    insert enum('y', 'n') 254/s            15%               14%                    --
                           Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
    insert tinyint(1)     234/s                --            -3%                   -5%
    insert char(1)        242/s                3%             --                   -2%
    insert enum('y', 'n') 248/s                6%             2%                    --
                           Rate insert enum('y', 'n') insert tinyint(1) insert char(1)
    insert enum('y', 'n') 189/s                    --               -6%           -19%
    insert tinyint(1)     201/s                    7%                --           -14%
    insert char(1)        234/s                   24%               16%             --
                           Rate insert char(1) insert enum('y', 'n') insert tinyint(1)
    insert char(1)        204/s             --                   -4%               -8%
    insert enum('y', 'n') 213/s             4%                    --               -4%
    insert tinyint(1)     222/s             9%                    4%                --
    

    似乎在大多数情况下, enum('y', 'n') 插入速度更快。

                           Rate select char(1) select tinyint(1) select enum('y', 'n')
    select char(1)        188/s             --               -7%                   -8%
    select tinyint(1)     203/s             8%                --                   -1%
    select enum('y', 'n') 204/s             9%                1%                    --
                           Rate select char(1) select tinyint(1) select enum('y', 'n')
    select char(1)        178/s             --              -25%                  -27%
    select tinyint(1)     236/s            33%                --                   -3%
    select enum('y', 'n') 244/s            37%                3%                    --
                           Rate select char(1) select tinyint(1) select enum('y', 'n')
    select char(1)        183/s             --              -16%                  -21%
    select tinyint(1)     219/s            20%                --                   -6%
    select enum('y', 'n') 233/s            27%                6%                    --
                           Rate select tinyint(1) select char(1) select enum('y', 'n')
    select tinyint(1)     217/s                --            -1%                   -4%
    select char(1)        221/s                1%             --                   -2%
    select enum('y', 'n') 226/s                4%             2%                    --
                           Rate select char(1) select tinyint(1) select enum('y', 'n')
    select char(1)        179/s             --              -14%                  -20%
    select tinyint(1)     208/s            17%                --                   -7%
    select enum('y', 'n') 224/s            25%                7%                    --
    

    选择也似乎是 enum . 代码可以 found here

        3
  •  10
  •   Matchu    15 年前

    使用tinyint是比较标准的做法,它可以让您更容易地检查字段的值。

    // Using tinyint 0 and 1, you can do this:
    if($row['admin']) {
        // user is admin
    }
    
    // Using char y and n, you will have to do this:
    if($row['admin'] == 'y') {
        // user is admin
    }
    

    我不是MySQL内部工作的专家,但它直观地感觉到检索和排序整型字段比字符字段更快(我只是感觉“a”>“z”比0>1更有效),从计算的角度来看,0和1是标准的开/关标志,这让我感觉更熟悉。所以整数的存储似乎更好,感觉更好,并且在代码逻辑中更容易使用。0/1绝对是我的赢家。

    您还可以注意到,在某种程度上,这也是MySQL的官方位置,从 their documentation :

    bool,boolean:这些类型是 TiNyIn(1)。零值是 被认为是错误的。非零值为 认为是真的。

    如果MySQL将tinyint(1)等同于boolean,那么这似乎是一种可行的方法。

        4
  •  4
  •   Jan Fabry    15 年前

    要确定这一点,您应该对其进行基准测试。或者要知道,从整个项目的宏观角度来看,这可能没有那么重要。

    char列有编码和排序,比较它们可能涉及编码之间不必要的切换,所以我猜int会更快。出于同样的原因,我认为更新int列的索引也更快。不过,这也没什么关系。

    CHAR 可以占用多个字节,具体取决于您选择的字符集和表选项。有些字符需要三个字节进行编码,因此MySQL有时会保留这些空间,即使您只使用 y n .

        5
  •  2
  •   Dave Markle    15 年前

    他们两个都会离得很近,所以没关系。如果你觉得有必要问这个问题,那么你就过于优化了。使用最符合逻辑的。

        6
  •  1
  •   Powerlord    15 年前

    如果指定类型 BOOL BOOLEAN 在MySQL中创建表时,列类型创建为 TINYINT(1) . 这大概是两者中的更快的一个。

    Documentation

    也:

    我们打算实现完整的布尔值 类型处理,符合 标准SQL,未来的MySQL 释放。

        7
  •  1
  •   zombat    15 年前

    虽然我的直觉是tinyint上的索引比char(1)上的索引快,因为没有字符串处理开销(排序规则、空白等),但我没有任何事实来支持这一点。我的猜测是,没有值得担心的显著性能差异。

    但是,因为您使用的是PHP,所以将其存储为tinyint就更有意义了。使用1/0值等同于使用 true false ,即使它们作为字符串返回到PHP,也可以这样处理。你只需做一个 if ($record['field']) 将结果作为布尔检查,而不是一直在“y”和“n”之间转换。

        8
  •  0
  •   streetparade    15 年前
     TINYINT    1 Byte
    CHAR(M)     M Bytes, 0 <= M <= 255
    

    有什么不同吗?

    推荐文章