数据库中将数字类型存储成字符型有哪些坏处?

2024-02-29 22:32

本文主要是介绍数据库中将数字类型存储成字符型有哪些坏处?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    工作中经常见到一些设计粗糙的数据库,其中将数字类型的字段定义和存储成字符型是一种比较常见的情况。部分开发同学或者非数据库岗位很多为了图方便,往往又不在意这些细节,除非等到出现可见的或者一些不可见的问题时才会去研究隐藏其后的真相。所以,这里简单总结一下,在数据库系统中,将数字类型存储成字符类型会有哪些不好的地方。以关系型数据库MySQL示例。

    ①字符类型往往比数字类型占用更多的存储

    首先,字符类型往往占用更多的存储,但非总是占用更多的存储。MySQL以固定长度存储数字类型:TINYINT、SMALLINT、MEDIUMINT、INT和BIGINT分别占用1、2、3、4和8个Byte存储。所以,就“1024”这个数值,如果以BIGINT、CHAR(4)和VARCHAR存储,不考虑其他,分别需要8、4和5个Byte存储(VARCHAR类型以是否存储了超过255个字符为界限分别需要额外1个或者2个Byte来记录存储长度)。但实际使用中,我们遇到的数字类型,其值域或者说取值空间是很宽大的,或者刚好可以放入一个较小的数字类型定义中。绝大多数情况下,总是可以通过选用数字类型从而节省存储空间。文件型数据库,数据最终是存储在磁盘上的文件,当需要对其查询时再读取到内存中。所以,更少的存储空间消耗与更高的查询性能是直接相关的。

    ②数字类型存储成字符类型可能使索引失效

    字段间进行比较时,如果字段类型不一致,在查询之前需要类型转换,否则无法直接进行比较。因为额外的类型转换操作,使得字段上的索引不可用。因此,将数字类型存储成字符类型,并且为其定义了索引,当其与其他数字类型字段关联查询时,该索引就失效了。

    ③数字类型存储成字符类型可能使部分SQL函数和命令失效

    数字的计算比较是作为一个整体在CPU中进行的。当数字类型存储成字符型时,会受到编码和排序规则影响;对字符型的查询是从左往右一个字符一个字符依次进行的,即最左前缀匹配。因此,将字符型数字直接传入部分函数或命令会使结果失真。

    首先创建两张示例表,插入相同的数据,但数据类型定义不一致。

CREATE TABLE `i` (`i` INT(11) NULL DEFAULT NULL
)
;
INSERT INTO `i` (`i`) VALUES (4);
INSERT INTO `i` (`i`) VALUES (8);
INSERT INTO `i` (`i`) VALUES (11);
INSERT INTO `i` (`i`) VALUES (23);
INSERT INTO `i` (`i`) VALUES (1024);
INSERT INTO `i` (`i`) VALUES (2147483647);
CREATE TABLE `s` (`s` VARCHAR(50) NULL DEFAULT NULL
)
;
INSERT INTO `s` (`s`) VALUES ('4');
INSERT INTO `s` (`s`) VALUES ('8');
INSERT INTO `s` (`s`) VALUES ('11');
INSERT INTO `s` (`s`) VALUES ('23');
INSERT INTO `s` (`s`) VALUES ('1024');
INSERT INTO `s` (`s`) VALUES ('2147483647');

    数字类型存储成字符型使得SQL查询结果失真。

mysql> SELECT MAX(i.i) FROM i;
+------------+
| MAX(i.i)   |
+------------+
| 2147483647 |
+------------+
1 row in set (0.00 sec)mysql> SELECT MAX(s.s) FROM s;
+----------+
| MAX(s.s) |
+----------+
| 8        |
+----------+
1 row in set (0.00 sec)
mysql> SELECT i.i FROM i ORDER BY i.i;
+------------+
| i          |
+------------+
|          4 |
|          8 |
|         11 |
|         23 |
|       1024 |
| 2147483647 |
+------------+
6 rows in set (0.00 sec)mysql> SELECT s.s FROM s ORDER BY s.s;
+------------+
| s          |
+------------+
| 1024       |
| 11         |
| 2147483647 |
| 23         |
| 4          |
| 8          |
+------------+
6 rows in set (0.00 sec)

    为了得到预想的数值结果,必须额外进行一次数据类型转换操作,包括隐式转换和显式转换两种方式。隐式转换是进行一个简单的不改变数值大小的数学计算;显式转换是借助CAST或者CONVERT函数。隐式操作在开发维护工作中往往就是出问题的根源,所以如果真的到了需要进行类型转换的时候,建议使用标准SQL规范的CAST。

mysql> SELECT MAX(s.s + 0) FROM s;
+--------------+
| MAX(s.s + 0) |
+--------------+
|   2147483647 |
+--------------+
1 row in set (0.01 sec)mysql> SELECT MAX(CAST(s.s AS DECIMAL)) FROM s;
+---------------------------+
| MAX(CAST(s.s AS DECIMAL)) |
+---------------------------+
|                2147483647 |
+---------------------------+
1 row in set (0.00 sec)

 

 

    参考:

https://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_max

https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast

这篇关于数据库中将数字类型存储成字符型有哪些坏处?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760316

相关文章

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

mysql数据库重置表主键id的实现

《mysql数据库重置表主键id的实现》在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,本文主要介绍了mysql数据库重置表主键id的实现,具有一定的参考价值,感兴趣的可以了... 目录关键语法演示案例在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,当我们

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

java字符串数字补齐位数详解

《java字符串数字补齐位数详解》:本文主要介绍java字符串数字补齐位数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java字符串数字补齐位数一、使用String.format()方法二、Apache Commons Lang库方法三、Java 11+的St

Oracle存储过程里操作BLOB的字节数据的办法

《Oracle存储过程里操作BLOB的字节数据的办法》该篇文章介绍了如何在Oracle存储过程中操作BLOB的字节数据,作者研究了如何获取BLOB的字节长度、如何使用DBMS_LOB包进行BLOB操作... 目录一、缘由二、办法2.1 基本操作2.2 DBMS_LOB包2.3 字节级操作与RAW数据类型2.

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES

Python如何查看数据的类型

《Python如何查看数据的类型》:本文主要介绍Python如何查看数据的类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python查看数据的类型1. 使用 type()2. 使用 isinstance()3. 检查对象的 __class__ 属性4.