zoukankan      html  css  js  c++  java
  • MySQL数据类型DECIMAL用法

    MySQL DECIMAL数据类型用于在数据库中存储精确的数值。我们经常将DECIMAL数据类型用于保留准确精确度的列,例如会计系统中的货币数据。
    要定义数据类型为DECIMAL的列,请使用以下语法:
    1
    column_name  DECIMAL(P,D);
    在上面的语法中:
    • P是表示有效数字数的精度。 P范围为1〜65。
    • D是表示小数点后的位数。 D的范围是0~30。MySQL要求D小于或等于(<=)P。
    DECIMAL(P,D)表示列可以存储D位小数的P位数。十进制列的实际范围取决于精度和刻度。
    与INT数据类型一样,DECIMAL类型也具有UNSIGNED和ZEROFILL属性。 如果使用UNSIGNED属性,则DECIMAL UNSIGNED的列将不接受负值。
    如果使用ZEROFILL,MySQL将把显示值填充到0以显示由列定义指定的宽度。 另外,如果我们对DECIMAL列使用ZERO FILL,MySQL将自动将UNSIGNED属性添加到列。
    以下示例使用DECIMAL数据类型定义的一个叫作amount的列。
    1
    amount DECIMAL(6,2);
    在此示例中,amount列最多可以存储6位数字,小数位数为2位; 因此,amount列的范围是从-9999.99到9999.99。
    MySQL允许使用以下语法:
    1
    column_name DECIMAL(P);
    这相当于:
    1
    column_name DECIMAL(P,0);
    在这种情况下,列不包含小数部分或小数点。
    此外,我们甚至可以使用以下语法。
    1
    column_name DECIMAL;
    在这种情况下,P的默认值为10。
     
    MySQL DECIMAL存储
    MySQL分别为整数和小数部分分配存储空间。 MySQL使用二进制格式存储DECIMAL值。它将9位数字包装成4个字节。
    对于每个部分,需要4个字节来存储9位数的每个倍数。剩余数字所需的存储如下表所示:
    剩余数字
    0
    0
    1–2
    1
    3–4
    2
    5–6
    3
    7-9
    4
    例如,DECIMAL(19,9)对于小数部分具有9位数字,对于整数部分具有19位= 10位数字,小数部分需要4个字节。 整数部分对于前9位数字需要4个字节,1个剩余字节需要1个字节。DECIMAL(19,9)列总共需要9个字节。
     
    MySQL DECIMAL数据类型和货币数据
    经常使用DECIMAL数据类型的货币数据,如价格,工资,账户余额等。如果要设计一个处理货币数据的数据库,则可参考以下语法 -
    1
    amount DECIMAL(19,2);
    但是,如果您要遵守公认会计原则(GAAP)规则,则货币栏必须至少包含4位小数,以确保舍入值不超过$0.01。 在这种情况下,应该定义具有4位小数的列,如下所示:
    1
    amount DECIMAL(19,4);
     
    MySQL DECIMAL数据类型示例
    第一步,创建一个名为test_order的新表,其中包含三列:id,description和cost。
    CREATE TABLE test_order (
        id INT PRIMARY KEY AUTO_INCREMENT,
        description VARCHAR(255),
        cost DECIMAL(19, 4) NOT NULL
    );
    第二步,将资料插入test_order表。
    INSERT INTO test_order (description, cost)
    VALUES ('Bicycle', 500.34),
        ('Seat', 10.23),
        ('Break', 5.21);
    第三步,从test_order表查询数据。
    SELECT * from test_order
    第四步,更改cost列以包含ZEROFILL属性。
    ALTER TABLE test_order
        MODIFY COLUMN cost DECIMAL(19, 4) ZEROFILL;
    第五步,再次查询test_order表。
    如上所见,在输出值中填充了许多零。
    因为zerofill,当我们插入负值会报
    第六步、修改DECIMAL类型长度和小数位数,则表里的原始数据会发生截取:
    mysql> ALTER TABLE test_order MODIFY cost DECIMAL(5,2) zerofill;
    Query OK, 3 rows affected (0.06 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    mysql> select * from test_order;
    +----+-------------+--------+
    | id | description | cost   |
    +----+-------------+--------+
    |  1 | Bicycle     | 500.34 |
    |  2 | Seat        | 010.23 |
    |  3 | Break       | 005.21 |
    +----+-------------+--------+
    3 rows in set (0.00 sec)
     
    第七步、验证以下结论:
    -- 整数的位数必须小于等于P-D,不然报错。小数的位数可以大于D位。多出D位时会做四舍五入,截取到D位。即当数值在其取值范围之内,小数位多了,则四舍五入后直接截断多出的小数位。
    -- 以上均不包括小数点、符号的位数。数字的总长度是P位,保存后的小数位最多是D位。如果保存后是整数,小数位不会补0。
    如下表所示:P=5,D=2
     
    mysql> show create table test_order G;
    *************************** 1. row ***************************
           Table: test_order
    Create Table: CREATE TABLE `test_order` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `description` varchar(255) DEFAULT NULL,
      `cost` decimal(5,2) unsigned zerofill DEFAULT NULL, -- 取值范围是 -999.99 到 999.99,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
    1 row in set (0.00 sec)
     
    1)小数部分多出位数四舍五入:
    mysql> INSERT INTO test_order(description,cost) values('car',123.2123456);
    Query OK, 1 row affected, 1 warning (0.00 sec)
    mysql> show warnings;
    +-------+------+-------------------------------------------+
    | Level | Code | Message                                   |
    +-------+------+-------------------------------------------+
    | Note  | 1265 | Data truncated for column 'cost' at row 1 |
    +-------+------+-------------------------------------------+
    1 row in set (0.00 sec)
    mysql> select * from test_order;
    +----+-------------+--------+
    | id | description | cost   |
    +----+-------------+--------+
    |  1 | Bicycle     | 500.34 |
    |  2 | Seat        | 010.23 |
    |  3 | Break       | 005.21 |
    |  4 | car         | 123.21 |
    +----+-------------+--------+
    4 rows in set (0.00 sec)
    2)整数的位数必须小于等于P-D,不然报错,
    若数值在其取值范围之外,则直接报Out of range value错误。
    mysql> INSERT INTO test_order(description,cost) values('cars',3333.2692);
    ERROR 1264 (22003): Out of range value for column 'cost' at row 1
    3)小数部分多出位数四舍五入:
    mysql> INSERT INTO test_order(description,cost) values('cars',33.2692) ;
    Query OK, 1 row affected, 1 warning (0.01 sec)
    mysql> show warnings;
    +-------+------+-------------------------------------------+
    | Level | Code | Message                                   |
    +-------+------+-------------------------------------------+
    | Note  | 1265 | Data truncated for column 'cost' at row 1 |
    +-------+------+-------------------------------------------+
    1 row in set (0.00 sec)
    mysql> select * from test_order;
    +----+-------------+--------+
    | id | description | cost   |
    +----+-------------+--------+
    |  1 | Bicycle     | 500.34 |
    |  2 | Seat        | 010.23 |
    |  3 | Break       | 005.21 |
    |  4 | car         | 123.21 |
    |  5 | cars        | 033.27 |
    +----+-------------+--------+
    5 rows in set (0.00 sec)
  • 相关阅读:
    什么样的代码称得上是好代码?
    九年程序人生 总结分享
    Docker入门 第一课 --.Net Core 使用Docker全程记录
    阿里云 Windows Server 2012 r2 部署asp.net mvc网站 平坑之旅
    Visual studio 2015 Community 安装过程中遇到问题的终极解决
    Activiti6.0 spring5 工作流引擎 java SSM流程审批 项目框架
    java 进销存 库存管理 销售报表 商户管理 springmvc SSM crm 项目
    Leetcode名企之路
    24. 两两交换链表中的节点
    21. 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/niuben/p/12825529.html
Copyright © 2011-2022 走看看