【问题标题】:Signed or unsigned in MySQL在 MySQL 中签名或未签名
【发布时间】:2010-10-03 10:56:46
【问题描述】:

我想知道在 MySQL 中使用 UNSIGNED 标志定义一些整数字段有什么积极影响吗?它是否使查询更快或数据库更小?还是只在担心上限的时候才去管它?

【问题讨论】:

标签: mysql database-design


【解决方案1】:

根据 MySQL 5.1 手册的section 10.2

在非严格模式下,当 超出范围的值被分配给 整数列,MySQL 存储值 代表对应的 列数据类型的端点 范围。如果您将 256 存储到 TINYINT 或 TINYINT UNSIGNED 列,MySQL 分别存储 127 或 255 个。什么时候 浮点或定点列 被分配的值超过 指定的隐含范围(或 默认)精度和规模,MySQL 存储代表的值 该范围的相应端点。

因此,只有在您关心上限时才真正需要使用 UNSIGNED。此外,添加 UNSIGNED 不会影响列的大小,只是数字是 represented

【讨论】:

  • 此外,对于那些只存储无符号值的情况,索引的性能也有所提高。就像@kevin-loney 所说,它可以节省索引上限值的时间。请参阅article that I had wrote 关于使用无符号类型而不是有符号的。
  • 你是国王,国王,兄弟!你刚刚为我节省了很多脑力... 通过上面的管理。 :-) 谢谢!
【解决方案2】:

除非您试图从价值中获得最大收益并且不需要负值,否则这无关紧要。

例如,假设您要存储 0-255。

您可以使用 tinyint,但前提是您将其用作 unsigned。

我见过的很多数据库,人们都懒得这样优化,最后得到一些相当大的表,因为他们一直都在使用 INT。

不过,如果您说的是 int 与 unsigned int,则根本没有性能影响或空间影响。

从标准的角度来看,我总是使用无符号,并且仅在我知道需要负值时才使用有符号。

【讨论】:

    【解决方案3】:

    在性能或存储方面,完全一样。

    作为一般规则,请使用更适合您的值:如果您只需要正值,请将值存储为 UNSIGNED,否则,让它成为默认值 [SIGNED]。

    为 PRIMARY AUTOINCREMENT 列设置 SIGNED 值时会出现一个问题:自动生成的数字的计数从 1(不是最小的负数)开始,并且可能的值将更早结束,因为您将只使用值的一半。所以在这种情况下(PRIMARY + AUTOINCREMENT 列)最好存储为 UNSIGNED。

    【讨论】:

      【解决方案4】:

      当列只包含正数时使用无符号。

      它不会影响列上的任何 I/O 性能,因为它仍会占用完全相同的空间量。

      【讨论】:

        【解决方案5】:

        它将提高性能,假设您要搜索数量

        没有“未签名”: 流程,由于数量字段是一个“int”并且你有这个字段的索引,所以MySQL会定义范围为-2147483648到500,它会根据这个范围得到结果。

        使用“未签名”: 流程,由于数量字段是一个“int”和“unsigned”,并且你有这个字段的索引,所以MySQL会将范围定义为0到500,它会根据这个范围得到结果。

        【讨论】:

          【解决方案6】:

          在这里,您可以看到 MySQL documentation 的 SIGNED 与 UNSIGNED INT 的范围。您很快就会注意到 UNSIGNED INT 的下限始终为 0,因此它永远不会是负数。

          Type    Storage Minimum Value   Maximum Value
                  (Bytes) (Signed/Unsigned)   (Signed/Unsigned)
          TINYINT     1   -128            127
                          0               255
          SMALLINT    2   -32768          32767
                          0               65535
          MEDIUMINT   3   -8388608        8388607
                          0               16777215
          INT         4   -2147483648     2147483647
                          0               4294967295
          BIGINT      8   -9223372036854775808    9223372036854775807
                          0               18446744073709551615
          

          【讨论】:

            【解决方案7】:

            警告,Unsigned Int (UINT) 和实体框架或 ADO.NET 存在问题。它可能涉及 MySql 连接器版本 6 的集成问题。

            根据我的经验,UInt 被 EF 读取为Long,这可能会引发一些精度问题,因为UInt 不是Long。任何不熟悉该问题的人都可能会感到头疼。

            其他问题:

            Integration problem between EF and Mysql Connector 6

            DBContext cannot use UINT

            EF provider trouble with UINT

            【讨论】:

              【解决方案8】:

              我更喜欢使用 UNSIGNED SMALLINT(或 MEDIUMINT)而不是 SIGNED INT。 它节省了 2 个(或 1 个)bytes,这有时会在大型数据集上提供更好的性能,尤其是索引列。

              【讨论】:

                猜你喜欢
                • 2018-10-30
                • 2018-05-14
                • 1970-01-01
                • 1970-01-01
                • 2021-12-06
                • 1970-01-01
                • 2017-08-17
                • 2017-02-19
                • 1970-01-01
                相关资源
                最近更新 更多