mysql:列类型之decimal、numeric
环境:
- 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]]
如: decimal
、decimal(5)
以及decimal(5,2)
都是可以的。
上面的M
表示总共有多少数字,D
表示小数点后面有几位。
如:45.123
的 M
是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了,M
和D
的默认值也体现了出来。
2. 数据库插入decimal数据的过程
如果我们定义decimal(5,2)
,那么当我们插入数据时,会先检查小数点点是否超过3位(5-2),超过的直接报异常,然后在检查小数点后的位数是否超过2位,如果超过的话就4舍五入,最后插入到数据库。
如:
- 插入
123.45
、12.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. 测试M
和D
的最大值:
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相关推荐
- MySQL列类型之——数值类型
如想进一步了解有关mysql的信息请点击http://dev.mysql.com/doc/refman/5.1/zh/column-types.html MySQL支持多种列类型:数值类型.日期/时间 ...
- 以下不属于mysql列类型的是什么意思_下列 ________ 类型不是 MySQL 中常用的的数据类型。_学小易找答案...
[简答题]工作区跳线的制作 请依据EIA568国际标准,制作一根直通线(即两端都是EIA568B线芯排布规律) 做好网线后,请拍照上传作业. [单选题]UNIQUE 惟一索引的作用是 ( ) : [简 ...
- Mysql列类型-数值型
2019独角兽企业重金招聘Python工程师标准>>> 一.整数型: 1.取值范围: tinyint smallint mediumint int bigin ...
- mysql 常用的列类型_MySQL 常用列类型
日期和时间类型为DATETIME.DATE.TIMESTAMP.TIME和YEAR. 注意:在MySQL中,日期时间值使用单引号引起来. 相当于Java中Date,Calender. 最常用的整数类型 ...
- mysql:列类型之时间日期
环境: window10 vs2022 .net 6 mysql 8.0.25 DBeaver 参考: <MSDN:浮点数值类型(C# 引用)> <mysql:11.2 Date a ...
- sqlite mysql pgsql_比较MySQL,PostgreSQL和SQLite中的数据库列类型?(跨图)
小编典典 我会做不同的事情清单: MySQL中的MEDIUMINT是一个奇怪的鸭子(3个字节).我会避免它,但否则也将其映射到INTEGER. MySQL BOOLEAN(别名BOOL,别名TINYI ...
- 深入浅出Mysql - 基础篇(列类型/运算符/函数)
深入浅出Mysql - 基础篇(列类型/运算符/函数) 每一个常量.变量和参数都有数据类型,它用来指定一定的存储格式.约束和有效范围.MySQL提供了多种数据类型,主要包括数值型.字符串类型.日期和时 ...
- mysql取得列类型_Mysql列类型
数值型 整型: tinyint:微小的列类型,1个字节,默认有符号,存储范围:-128--127 可选属性:tingyint(M) unsigned zerofill M:宽度(在0填充(zerofi ...
- 20141230 mysql数值类型和列属性一
20141230 mysql数值类型和列属性一 回顾 数据库基础知识,关系型数据库(行/记录,列/字段,SQL) 基本SQL操作:库操作,表操作(字段)和数据操作 字符集 校对集 1. 什么是校对集? ...
最新文章
- 如何使用工具包 (NLTK) 开发NLP 项目?(附教程)
- Windows Server 2019 开发环境
- 向人类进化史看齐,编程语言的“别样”编年史
- mysql utc 下取得昨天的时间段。
- boost::boost::directed_graph用法的测试程序
- python 中del 的用法
- python 文件相似度分析_使用Python做人群相似度分析
- python创建矩阵_python中Numpy的属性与创建矩阵
- VMwar配置静态ip
- XNA中的中文输入(一)
- 1196:踩方格(递推)
- Android全面屏最大纵横比适配
- day69 【哈希,HashSet,HashMap】
- HTML5情人节礼物2(女友3D相册)
- 如何使用脚本语言将typora的内容自动同步到gitee上
- w7旗舰版的计算机管理,win7旗舰版系统获取administrator权限的方法
- 台式计算机开始不显示,台式机连接投影仪不显示怎么办
- 2043 Problem F 小白鼠排队
- ConvMAE实战:使用ConvMAE实现对植物幼苗的分类(非官方)(一)
- 5 个 JavaScript “罕见”原生的 API
热门文章
- 2021-03-13高级经理计算题:成本效益分析
- 【SPA】SPA单页面应用详解
- Max22——导出FBX让windows默认3D查看器可见模型和贴图
- linux报错Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile解决方法
- HTML语言全称叫超文本标记语言,其中的“标记“如何理解,“超文本”又如何理解?
- 四川大学计算机学院赵怡,【喜讯】我校计算机学院学子在蓝桥杯大赛全国总决赛中再获佳绩...
- 小型便携式AIS接收机dAI01
- 公网IP TCP服务器调试
- Linux查看磁盘存储空间大小
- 关于RapidSSL证书