MySQL:十进制数据类型的大小

17

我从服务器上接收到一些值,需要将它们存储在我的数据库中。虽然我不是MySQL专家,但对于基本的输入/输出,我还是了解得足够好的。目前,我正在尝试确定在存储以下小数时应该使用的长度。

tax_rate [DECIMAL ?,?]: value(0.014840000000)
units [DECIMAL ?,?]: value(1.00)
initial_charge [DECIMAL ?,?]: value(2.5110)
charge [DECIMAL ?,?]: value(2.8967)
link_tax [DECIMAL ?,?]: value(0.385652)
exempt [DECIMAL ?,?]: value(0.0000)
tax [DECIMAL ?,?]: value(0.042986)
base_price [DECIMAL ?,?]: value(41.8500)

我希望有人能够建议我使用哪个正确的大小来容纳这些值,并解释为什么选择这些值。或者提供一篇深入解释MySQL小数的文章。

任何帮助都将不胜感激。

谢谢!

-------编辑--------

阅读了MySQL文档后,关于确定小数类型的大小有非常好的解释。这是我为我的用例设置的大小:

tax_rate [DECIMAL 15,12]: value(0.014840000000) ? max(999.999999999999)
units [DECIMAL 6,2]: value(1.00) ? max(9999.99)
initial_charge [DECIMAL 9,4]: value(2.5110) ? max(99999.9999)
charge [DECIMAL 9,4]: value(2.8967) ? max(99999.9999)
link_tax [DECIMAL 9,6]: value(0.385652) ? max(999.999999)
exempt [DECIMAL 9,4]: value(0.0000) ? max(9999.9999)
tax [DECIMAL 10,6]: value(0.042986) ? max(999999.999999)
base_price [DECIMAL 10,4]: value(41.8500) ? max(999999.9999)

3
深入阅读:官方文档位于 http://dev.mysql.com/doc/refman/5.0/en/fixed-point-types.html,介绍了 MySQL 中的定点数类型。 - Amadan
3个回答

51

来自MySQL

DECIMAL列的声明语法是DECIMAL(M,D)。在MySQL 5.1中,参数值的范围如下:

M是数字的最大位数(精度),范围为1到65(MySQL的旧版本允许1到254)。

D是小数点后面的数字位数(刻度),范围为0到30,并且不能大于M。

考虑这个数字:123456789.12345,这里的M14D5,然后根据此原则,可以为每个列设置DECIMALS(M,D),基于它们的预期最大值。


1
太棒了。这基本上就是总结...我会编辑我的帖子以反映正确的值。 - user0000001
1
@zonabi D始终包含在M中。 - machineaddict

2
在MySQL中,DECIMAL(M,D) /或等效的NUMERIC(M,D)/:

  • M是数字的总位数,
  • D是小数部分的位数。

以下是一个适合于(至少)DECIMAL(8,3)的数字示例:

Integer  Fractional
   part  part (D)
   ┌─┴─┐ ┌┴┐
   58282.349
   └───┬───┘
       M

在解释细节之前,这里有一个对上述示例的预告答案。
3 bytes   2 bytes
   ┌─┴─┐ ┌┴┐
   58282.349

根据文档,数字的整数部分和小数部分所使用的字节数是分开确定的。但方法是相同的:每9位数字的倍数需要4个字节,任何剩余的数字需要一些4个字节的分数,如下表所示:
剩余数字 字节数
0 0
1-2 1
3-4 2
5-6 3
7-9 4
以下是一些例子:
DECIMAL(M,D) 示例 整数位字节数 小数位字节数 总字节数
DECIMAL(4,0) 1822 2 - 2
DECIMAL(9,0) 764891821 4 - 4
DECIMAL(10,0) 2520521346 5 - 5
DECIMAL(19,0) 4638624678248624756 9 - 9
DECIMAL(5,2) 452.76 2 1 3
DECIMAL(9,2) 7567634.55 4 1 5
DECIMAL(11,2) 146249930.28 4 1 5
DECIMAL(18,2) 5852340342645782.52 8 1 9
DECIMAL(20,2) 414576457834678934.38 8 1 9
DECIMAL(6,5) 8.34801 1 3 4
DECIMAL(5,5) .73678 - 3 3

负数也属于相同的范围。例如:

  • DECIMAL(3,0) 可以存储介于 -999999 之间的数字。
  • DECIMAL(4,3) 可以存储介于 -9.9999.999 之间的数字。

1

由于接受的答案让我感到不够满意,我在一个包含多个列定义为DECIMAL DEFAULT NULL(注意MD没有值)的表上运行了SHOW CREATE TABLE

结果如下。

data_warehouse as davidg Wed Dec 05 12:10:36 2018 >SHOW CREATE TABLE erth_calendarmonths_historic_usage_preload;
+--------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table                                      | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+--------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| erth_calendarmonths_historic_usage_preload | CREATE TABLE `erth_calendarmonths_historic_usage_preload` (
  `market` varchar(100) NOT NULL,
  `commodity` varchar(100) NOT NULL,
  `account_number` varchar(100) NOT NULL,
  `meter_number` varchar(100) NOT NULL,
  `period_year_month` int(11) NOT NULL,
  `estimated_usage_amount` decimal(18,7) DEFAULT NULL,
  `unit` varchar(100) DEFAULT NULL,
  `meter_read_start_date_part_1` datetime DEFAULT NULL,
  `meter_read_end_date_part_1` datetime DEFAULT NULL,
  `gross_nonadjusted_usage_amount_part_1` decimal(10,0) DEFAULT NULL,
  `applied_nonadjusted_usage_amount_part_1` decimal(10,0) DEFAULT NULL,
  `meter_read_start_date_part_2` datetime DEFAULT NULL,
  `meter_read_end_date_part_2` datetime DEFAULT NULL,
  `gross_nonadjusted_usage_amount_part_2` decimal(10,0) DEFAULT NULL,
  `applied_nonadjusted_usage_amount_part_2` decimal(10,0) DEFAULT NULL,
  `utility_rate_class` varchar(100) DEFAULT NULL,
  `utility_rate_subclass` varchar(100) DEFAULT NULL,
  `load_profile` varchar(100) DEFAULT NULL,
  `hu_type` varchar(100) DEFAULT NULL,
  `type` varchar(100) DEFAULT NULL,
  `utility_duns` varchar(100) DEFAULT NULL,
  `create_date` datetime DEFAULT NULL,
  `update_date` datetime DEFAULT NULL,
  `UsedBuckets` tinyint(4) NOT NULL DEFAULT '0',
  PRIMARY KEY (`market`,`commodity`,`account_number`,`meter_number`,`period_year_month`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

前面的内容使得M和D的默认值不言自明;M = 10,而D = 0。毋庸置疑,这几乎肯定不是期望的结果。 你应该总是指定你的M和D值。

嗯,我不这么认为...我不知道为什么还没有人评论这个!如果您使用类似于DECIMAL(10,3) DEFAULT NULL的东西创建表格,我有一些信心这不会是问题。您从未告诉MySQL要存储多少小数位,它无法比“0小数位”更好地猜测,您知道!如果这仍然不能按预期工作,则肯定遇到了MySQL版本中的错误(如果其他人尚未这样做,请继续报告)。 - Fr0zenFyr
1
顺便提一下,根据文档 在标准SQL中,DECIMAL(M)语法等同于DECIMAL(M,0)。同样,DECIMAL语法等同于DECIMAL(M,0),其中实现允许决定M的值。MySQL支持这些变体形式的DECIMAL和NUMERIC语法。M的默认值为10。由于您从未定义M(精度)D(比例),因此它们分别成为100 - Fr0zenFyr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接