Smart猫小萌
MySQL最近改变了他们存储DECIMAL类型的方式。在过去,他们为每个数字存储字符(或nybbles),包括数字的ASCII(或nybble)表示 - vs - 二进制补码整数或其衍生物。DECIMAL的当前存储格式是一系列1,2,3或4字节整数,其位被连接以创建带有隐含小数点的二进制补码数,由您定义,并在您声明时存储在DB模式中列,并指定它的DECIMAL大小和小数点位置。举例来说,如果你采用32位int,你可以存储0 - 4,294,967,295之间的任何数字。这只能可靠地覆盖999,999,999,所以如果你扔出2位并使用(1 << 30 -1)你就什么也不放弃。仅使用4个字节覆盖所有9位数字比使用4个ASCII字符或8个nybble数字覆盖32位中的4位数字更有效。(一个nybble是4位,允许值0-15,超过0-9所需的值,但你不能通过转到3位来消除这种浪费,因为它只涵盖0-7的值)MySQL在线文档中使用的示例使用DECIMAL(18,9)作为示例。这比隐含小数点前面的9位数字和9位数字要短,如上所述,需要以下存储空间。18个8位字符:144位作为18个4位nybbles:72位作为2个32位整数:64位目前DECIMAL最多支持65位数字,如DECIMAL(M,D),其中M允许的最大值为65,D允许的最大值为30。为了不一次要求9位数的块,小于32位的整数用于使用1,2和3字节整数来添加数字。出于某种原因,无视逻辑,使用了签名而不是无符号的int,并且这样做,1位被抛出,从而产生以下存储能力。对于1,2和4字节的整数,丢失的位无关紧要,但对于3字节的int来说,这是一场灾难,因为整个数字由于丢失了这一位而丢失。使用7位int:0 - 99使用15位int:0 - 9,999使用23位int:0 - 999,999(0 - 9,999,999,带有24位int)1,2,3和4字节整数连接在一起形成“位池”DECIMAL用于将数字精确地表示为二进制补码整数。小数点未存储,暗示。这意味着数据库引擎不需要ASCII到int转换就可以将“数字”转换为CPU识别为数字的内容。没有舍入,没有转换错误,它是CPU可以操作的实数。对这个任意大整数的计算必须在软件中完成,因为这种数字没有硬件支持,但这些库非常陈旧且经过高度优化,已在50年前编写,以支持IBM 370 Fortran任意精度浮点数据。它们仍然比使用CPU整数硬件完成的固定大小整数代数慢,或者在FPU上进行浮点计算。就存储效率而言,因为float的指数附加到每个浮点数,隐含地指定小数点的位置,所以它是大量冗余的,因此对DB工作来说效率低。在数据库中,您已经知道小数点的位置在前面,并且表中具有DECIMAL列值的每一行只需要查看该小数点的放置位置的唯一规范,存储在模式中作为DECIMAL(M,D)的参数作为M和D值的含义。这里发现的关于哪种格式用于各种应用程序的许多评论是正确的,所以我不会强调这一点。我花时间在这里写这篇文章,因为无论是谁维护链接的MySQL在线文档都不理解上述任何内容,并且经过多次令人沮丧的尝试向他们解释它后,我放弃了。很好地表明他们对所写内容的理解程度有多差,这是对主题的非常混乱和难以理解的表现。最后,如果您需要高精度浮点计算,过去20年浮点代码已经取得了巨大进步,96位和四倍精度浮点数的硬件支持即将到来,但是如果存储值的操作很重要,那么有很好的任意精度库。