对比下不同RDBMS数据库中对字符数据类型处理的差异 - 为什么我们要尽量避免使用CHAR数据类型?

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 对比下不同RDBMS数据库中对字符数据类型处理的差异 - 为什么我们要尽量避免使用CHAR数据类型?

1 前言

大家好,我是明哥!

今天我们来对比下 ORACLE 与 MYSQL 中不同字符数据类型的异同,以避免因前期数据结构设计时数据类型选用不当,造成后续存储加工和处理数据时的各种坑。

2 ORACLE 与 MYSQL 中字符数据类型都有哪些

ORACLE 中内置的字符数据类型主要有以下三大类:

  • CHAR/NCHAR:存储固定长度的字符串,其中NCHAR使用 national character set;
  • VARCHAR2/VARCHAR/NVARCHAR2:存储变长字符串,其中 VARCHAR 等同于 VARCHAR2,NVARCHAR2 使用 national character set;
  • CLOB/NCLOB:存储大小可达 4GB 的字符串,其中 NCLOB 使用 national character set;

MYSQL 中字符数据类型主要有:

  • CHAR:存储固定长度的字符串;
  • VARCHAR:存储变长字符串
  • BLOB/TEXT:主要用来存储大的字符串。

可以看到:

  • 二者都有专门用来处理较大字符串的数据类型,如 CLOB/BLOB/TEXT;
  • 二者都有处理定长字符串的数据类型,如 CHAR;
  • 二者都有处理变长字符串的数据类型,如 VARCHAR;

以下我们重点对比下二者对定长和变长字段类型,即 CHAR 和 VARCHAR ,处理时的异同。

3 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的相同点在哪里?

3.1 ORACLE 和 MYSQL 对定长字段类型 CHAR 的存储处理类似,都会对用户传入的实际的字符串进行加工处理后再存储:

  • 如果用户传入的实际的字符串的长度,跟 DDL 语句中声明的该 CHAR 字段的长度相等,则直接存储用户传入的值;
  • 如果用户传入的实际的字符串的长度,小于 DDL 语句中声明的该 CHAR 字段的长度,ORACLE 和 MYSQL 都会在字段末尾补充空格(blank-pad),直到达到声明的长度;
  • 如果用户传入的实际的字符串的长度,大于 DDL 语句中声明的该 CHAR 字段的长度,ORACLE 和 MYSQL 都会报错退出(注意:MYSQL中,可以配置使用非 STRICT SQL MODE,此时会截断超常字段然后存储截断后的值并告警,但不会报错退出);

3.2 ORACLE 和 MYSQL 对变长字段类型 VARCHAR 的存储处理类似,都不会对用户传入的实际的字符串进行加工处理,而是直接校验存储:

-如果用户传入的实际的字符串的长度,小于或等于 DDL 语句中声明的该 VARCHAR 字段的最大长度,则直接存储用户传入的值;(实际存储的数据,都是字段值的实际长度和字段的具体值);

  • 如果用户传入的实际的字符串的长度,大于 DDL 语句中声明的该 VARCHAR 字段的最大长度,ORACLE 和 MYSQL 都会报错(注意:MYSQL中,是报错还是截断,跟超长字段是正常字段还是 trailing spaces,以及是否是 STRICT SQL MODE 有关);

3.3 ORACLE 和 MYSQL 对变长字段类型 VARCHAR 的取出处理类似

  • ORACLE 和 MYSQL 对变长字段类型 VARCHAR 的取出处理类似,都不会对实际存储的字段值做加工处理,而是直接返回,因为存储时已经做了校验和加工。

3.4 ORACLE 和 MYSQL 中都是 VARCHAR(ORACLE 中是 VARCHAR2)的存储空间使用率更好

  • ORACLE 和 MYSQL 中都是 VARCHAR(ORACLE 中是 VARCHAR2)的存储空间使用率更好,因为 CHAR 类型字段在实际长度不够时会在末尾补充空格(blank-pads)并存储这些 trailing blanks 而 VARCHAR 不会,所以 VARCHAR 可以更有效地存储数据,空间使用率更高。

4 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的不同点在哪里?

4.1 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的不同点,体现在如何取出 CHAR 类型的字段数据上:

  • ORACLE 会将存储的值原封不动地取出,不做任何加工,所以通过LENGTH()函数返回的,就是 DDL 语句中声明的长度(当然底层存储时 pad 了 space);
  • MYSQL 会将存储的值最右边的空格全部截取后再取出,所以通过LENGTH()函数返回的,不是 DDL 语句中声明的长度,而是字段的实际有效长度(当然底层存储时 pad 了 space);

4.2 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的不同点,体现在如何对比 CHAR 和 VARCHAR 类型的字段数据上:

  • Oracle 对 CHAR/NCHAR 采用的是 “blank-padded comparison semantics” 模式:如果对比的字段长度不同, Oracle 会在较短字段的末尾补充空格使得两者长度相同,然后再逐个字符进行比较。所以只有末尾空格数有差异的字段,对被认为是相等的字段;
  • Oracle 对 VARCHAR2/NVARCHAR2 采取的是 “non-padded comparison semantics” 模式:只有两个字段的长度相同且字符完全相同,才会被认为是相等的字段;
  • MySQL 对 CHAR, VARCHAR, 和 TEXT 采取的都是类似 ORACLE 的 “blank-padded comparison semantics” 的模式:即如果对比的字段长度不同, Oracle 会在较短字段的末尾补充空格使得两者长度相同,然后再逐个字符进行比较。所以只有末尾空格数有差异的字段,对被认为是相等的字段;

4 知识总结

  • ORACLE 和 MYSQL 都有对应变长字符串的数据类型,如 VARCHAR/VARCHAR2, 两者在数据的存储和取出上的处理类似;
  • ORACLE 和 MYSQL 都有对应定长字符串的数据类型,如 CHAR,两者对 CHAR 类型字段的存储处理类似,都会校验字段长度,并在字段不够时通过空格右补齐;
  • ORACLE 在取出 CHAR 类型字段时,不会做额外处理,会将存储的字段值直接取出;MYSQL 在取出 CHAR 类型字段时,会对存储的字段值做额外处理,会将字段最右端的空格截掉再返回;
  • Oracle 在对比 CHAR/NCHAR 类型字段时,采用的是 “blank-padded comparison semantics” 模式;
  • Oracle 在对比 VARCHAR2/NVARCHAR2 类型字段时,采取的是 “non-padded comparison semantics” 模式;
  • MySQL 在对比 CHAR, VARCHAR, 和 TEXT 类型字段时,采取的都是类似 ORACLE 的 “blank-padded comparison semantics” 的模式;

image.png

image.png

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
机器学习/深度学习 存储 关系型数据库
MySQL数据库:常用数据类型
【2月更文挑战第7天】
32 0
|
4月前
|
设计模式 NoSQL Java
常用的设计模式以及操作Redis、MySQL数据库、各种MQ、数据类型转换的方法
常用的设计模式以及操作Redis、MySQL数据库、各种MQ、数据类型转换的方法
|
5月前
|
存储 NoSQL 关系型数据库
Redis数据库 | 基本数据类型、特殊数据类型
Redis数据库 | 基本数据类型、特殊数据类型
47 0
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
106 1
|
7月前
|
存储 关系型数据库 MySQL
数据库基础入门 — 数据类型
数据库基础入门 — 数据类型
50 0
|
27天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
4月前
|
存储 SQL 关系型数据库
MySql中有哪些数据类型(数据库学习——三)
MySql中有哪些数据类型(数据库学习——三)
37 1
|
6天前
|
缓存 NoSQL 关系型数据库
在Python Web开发过程中:数据库与缓存,MySQL和NoSQL数据库的主要差异是什么?
MySQL与NoSQL的主要区别在于数据结构、查询语言和可扩展性。MySQL是关系型数据库,依赖预定义的数据表结构,使用SQL进行复杂查询,适合垂直扩展。而NoSQL提供灵活的存储方式(如JSON、哈希表),无统一查询语言,支持横向扩展,适用于处理大规模、非结构化数据和高并发场景。选择哪种取决于应用需求、数据模型及扩展策略。
17 0
|
5月前
|
存储 机器学习/深度学习 编解码
如何给图数据库 NebulaGraph 新增一种数据类型,以 Binary 为例
数据库通常会内置支持常用的数据类型,但特征处理又要用到 Embedding、Binary 类型,那么,如何在已有的数据类型中增加新的数据类型呢?
158 1
如何给图数据库 NebulaGraph 新增一种数据类型,以 Binary 为例
|
3月前
|
存储 关系型数据库 MySQL
MySQL技能完整学习列表4、数据库设计——1、数据类型
MySQL技能完整学习列表4、数据库设计——1、数据类型
43 0