环境:

  • window10
  • vs2022
  • .net 6
  • mysql 8.0.25
  • DBeaver

参考:
《mysql:11.1.3 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC》
《MSDN:浮点数值类型(C# 引用)》

1. decimal和numeric的定义

这两个是同一个意思,使用numeric定义的列会被转换成decimal。

使用的语法为:
decimal[M[,D]]
如: decimaldecimal(5)以及decimal(5,2)都是可以的。

上面的M表示总共有多少数字,D表示小数点后面有几位。
如:45.123M是5,d是3。

注意:M的默认值是10,最大值是65,D的默认值是0,最大值是30。

看下面测试:

create table test.test(t_decimal decimal,t_decimal5 decimal(5),t_decimal5_2 decimal(5,2),t_numeric numeric,  t_numeric_4 numeric(4),t_numeric_4_3 numeric(4,3)
)
-- 查看定义语句
show create table test.test-- 查看列类型
select c.TABLE_SCHEMA ,c.TABLE_NAME ,c.COLUMN_NAME ,c.ORDINAL_POSITION,c.DATA_TYPE,c.NUMERIC_PRECISION ,c.COLUMN_TYPE ,c.NUMERIC_SCALE
from information_schema.`COLUMNS` c  where TABLE_SCHEMA ='test' and TABLE_NAME ='test' order by ORDINAL_POSITION

输出如下:


可以看到:numeric被转换成decimal了,MD的默认值也体现了出来。

2. 数据库插入decimal数据的过程

如果我们定义decimal(5,2),那么当我们插入数据时,会先检查小数点点是否超过3位(5-2),超过的直接报异常,然后在检查小数点后的位数是否超过2位,如果超过的话就4舍五入,最后插入到数据库。

如:

  • 插入123.4512.1时,小数点前面没有超过3位,小数点后面也没有超过2位,直接插入到数据库;
  • 插入123.123时,小数点前面没超过3位,小数点后面超过2位,四设五入为 123.12,最终数据库中插入123.12
  • 插入1234.12时,小数点前面超过3位,直接报错:Out of range value
  • 插入1234.123时,小数点前面超过3位,直接报错:Out of range value

测试代码如下:

create table test.test(t_decimal decimal,t_decimal5 decimal(5),t_decimal5_2 decimal(5,2),t_numeric numeric,  t_numeric_4 numeric(4),t_numeric_4_3 numeric(4,3)
)
insert into test.test(t_decimal,t_decimal5,t_decimal5_2,t_numeric,t_numeric_4,t_numeric_4_3) values(1234567891,12345,123.45,1234567891,1234,1.234);insert into test.test(t_decimal5_2) values(123.45);-- 正常插入
insert into test.test(t_decimal5_2) values(12.1);-- 正常插入
insert into test.test(t_decimal5_2) values(123.123); -- 数据被四设五入
insert into test.test(t_decimal5_2) values(1234.123); -- 报错: Out of range value
insert into test.test(t_decimal5_2) values(1234.123); -- 报错: Out of range valueselect * from test.test

3. 测试MD的最大值:



4. c#中的使用方式

mysql中的decimal是定点小数,存储的是精确值,而c#中的float、double、decimal都是浮点型,存储的是近似数,所以c#中并没有很对称的数据类型。

但一般,我们使用c#中的decimal去表示mysql中的decimal也没问题,因为它的精度已经很高了,如下图:

为什么c#中没有定点小数呢,毕竟c#要考虑计算得。而数据库主要的任务是存储,事实上一旦在数据库中做运算,那么看似没问题的数据类型也会暴露出问题的。

如果,我们实在担心精度丢失,那么就直接用 string表示吧(注意:数据库和c#都要是string,因为ado.net自动读取后就是decimal已经失真了)。

下面是做了decimal失真的实验:

create table test(t_decimal28_15 decimal(28,15),t_decimal30_15 decimal(30,15)
)insert into test(t_decimal28_15,t_decimal30_15) values (1234567890123.123456789012345,123456789012345.123456789012345)
select * from test

输出:

可以看到,mysql中存储和读取都是没问题的,因为mysql使用定点小数存储,精度范围足够大,不会失真(decimal(M,D),M最大是65,D最大是30)。

使用c#读取:

//<PackageReference Include="MySqlConnector" Version="2.1.6" />
var connstring = "Server=127.0.0.1;Database=test;Uid=root;Pwd=123456;";
var conn = new MySqlConnector.MySqlConnection(connstring);
conn.Open();
var cmd = conn.CreateCommand();cmd.CommandText = @"drop table  if exists test";
cmd.ExecuteNonQuery();cmd.CommandText = @"create table test(t_decimal28_15 decimal(28,15),t_decimal30_15 decimal(30,15)
)";
cmd.ExecuteNonQuery();
cmd.CommandText = @"insert into test(t_decimal28_15,t_decimal30_15) values(1234567890123.123456789012345,123456789012345.123456789012345)";
cmd.ExecuteNonQuery();cmd.CommandText = "select * from test";
var reader = cmd.ExecuteReader();
reader.Read();
var t_decimal28_15 = reader.GetValue(0);//true,不失真
Console.WriteLine(t_decimal28_15.ToString() == "1234567890123.123456789012345");
var t_decimal30_15 = reader.GetValue(1);// false,出现失真(读取到的为:123456789012345.12345678901235,即最后一位小数发生四舍五入)
Console.WriteLine(t_decimal30_15.ToString() == "123456789012345.123456789012345");reader.Close();
conn.Close();

虽然上面c#测试的失真了,但是,我们真的需要这么高的精度吗?一般是不需要的。如果需要,请使用使用string存储编程。

mysql:列类型之decimal、numeric相关推荐

  1. MySQL列类型之——数值类型

    如想进一步了解有关mysql的信息请点击http://dev.mysql.com/doc/refman/5.1/zh/column-types.html MySQL支持多种列类型:数值类型.日期/时间 ...

  2. 以下不属于mysql列类型的是什么意思_下列 ________ 类型不是 MySQL 中常用的的数据类型。_学小易找答案...

    [简答题]工作区跳线的制作 请依据EIA568国际标准,制作一根直通线(即两端都是EIA568B线芯排布规律) 做好网线后,请拍照上传作业. [单选题]UNIQUE 惟一索引的作用是 ( ) : [简 ...

  3. Mysql列类型-数值型

    2019独角兽企业重金招聘Python工程师标准>>> 一.整数型: 1.取值范围: tinyint    smallint    mediumint    int    bigin ...

  4. mysql 常用的列类型_MySQL 常用列类型

    日期和时间类型为DATETIME.DATE.TIMESTAMP.TIME和YEAR. 注意:在MySQL中,日期时间值使用单引号引起来. 相当于Java中Date,Calender. 最常用的整数类型 ...

  5. mysql:列类型之时间日期

    环境: window10 vs2022 .net 6 mysql 8.0.25 DBeaver 参考: <MSDN:浮点数值类型(C# 引用)> <mysql:11.2 Date a ...

  6. sqlite mysql pgsql_比较MySQL,PostgreSQL和SQLite中的数据库列类型?(跨图)

    小编典典 我会做不同的事情清单: MySQL中的MEDIUMINT是一个奇怪的鸭子(3个字节).我会避免它,但否则也将其映射到INTEGER. MySQL BOOLEAN(别名BOOL,别名TINYI ...

  7. 深入浅出Mysql - 基础篇(列类型/运算符/函数)

    深入浅出Mysql - 基础篇(列类型/运算符/函数) 每一个常量.变量和参数都有数据类型,它用来指定一定的存储格式.约束和有效范围.MySQL提供了多种数据类型,主要包括数值型.字符串类型.日期和时 ...

  8. mysql取得列类型_Mysql列类型

    数值型 整型: tinyint:微小的列类型,1个字节,默认有符号,存储范围:-128--127 可选属性:tingyint(M) unsigned zerofill M:宽度(在0填充(zerofi ...

  9. 20141230 mysql数值类型和列属性一

    20141230 mysql数值类型和列属性一 回顾 数据库基础知识,关系型数据库(行/记录,列/字段,SQL) 基本SQL操作:库操作,表操作(字段)和数据操作 字符集 校对集 1. 什么是校对集? ...

最新文章

  1. 如何使用工具包 (NLTK) 开发NLP 项目?(附教程)
  2. Windows Server 2019 开发环境
  3. 向人类进化史看齐,编程语言的“别样”编年史
  4. mysql utc 下取得昨天的时间段。
  5. boost::boost::directed_graph用法的测试程序
  6. python 中del 的用法
  7. python 文件相似度分析_使用Python做人群相似度分析
  8. python创建矩阵_python中Numpy的属性与创建矩阵
  9. VMwar配置静态ip
  10. XNA中的中文输入(一)
  11. 1196:踩方格(递推)
  12. Android全面屏最大纵横比适配
  13. day69 【哈希,HashSet,HashMap】
  14. HTML5情人节礼物2(女友3D相册)
  15. 如何使用脚本语言将typora的内容自动同步到gitee上
  16. w7旗舰版的计算机管理,win7旗舰版系统获取administrator权限的方法
  17. 台式计算机开始不显示,台式机连接投影仪不显示怎么办
  18. 2043 Problem F 小白鼠排队
  19. ConvMAE实战:使用ConvMAE实现对植物幼苗的分类(非官方)(一)
  20. 5 个 JavaScript “罕见”原生的 API

热门文章

  1. 2021-03-13高级经理计算题:成本效益分析
  2. 【SPA】SPA单页面应用详解
  3. Max22——导出FBX让windows默认3D查看器可见模型和贴图
  4. linux报错Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile解决方法
  5. HTML语言全称叫超文本标记语言,其中的“标记“如何理解,“超文本”又如何理解?
  6. 四川大学计算机学院赵怡,【喜讯】我校计算机学院学子在蓝桥杯大赛全国总决赛中再获佳绩...
  7. 小型便携式AIS接收机dAI01
  8. 公网IP TCP服务器调试
  9. Linux查看磁盘存储空间大小
  10. 关于RapidSSL证书