本文来自李明子csdn博客(http://blog.csdn.net/free1985),商业转载请联系博主获得授权,非商业转载请注明出处!

1 引子

字符串类型的字段在各关系数据库中均占有重要地位。比如Oracle数据库中用于存储字符串类型数据的字段类型就超过了5种。遗憾的是,在日常工作中笔者发现很多开发者对这些类型并没有完整的认识,更不用说设计表结构时正确的选择字段类型了。本文将辨析Oracle数据库中表示字符串的各字段类型以及设计表结构时字段类型的选择依据。

2 字段类型介绍

Oracle数据库中,用于表示字符串类型的字段类型包括CHAR、VARCHAR2、VARCHAR、NCHAR、NVARCHAR2、CLOB和NCLOB等几种,下面我们来一一介绍这些类型。
2.1 CHAR
CHAR类型用于存储定长的字符串,字段长度的取值范围是1到2000字节,默认为1字节。因为CHAR是定长的,所以,当存储的字符串小于设置的字段长度时,Oracle将在字符串尾填充空格占位。比如我们定义了一个字段“TEST_CHAR CHAR(2)”,而插入的记录对应字段值为“a”,则从表中读取的记录的对应字段是填充了一个空格的“a ”。
对于CHAR类型值的比较,Oracle会在填充空格补齐到设置长度后进行。比如对于上例,当检索条件为“where TEST_CHAR=’a’”时是可以得到记录“a ”的。
另外,在定义CHAR的长度时可以使用单位名称BYTE或CHAR,默认为BYTE。即“TEST_CHAR CHAR(2 BYTE)”意为长度为2个字节的CHAR,而“TEST_CHAR CHAR(2 CHAR)”意为长度为2个字符的CHAR。
这里说的“字节”是存储字段信息所占用的物理存储空间,而“字符”则是指存储的信息的最小逻辑单位。当数据库使用单字节字符集时,一个字符的存储空间就是一个字节,而当数据库使用多字节字符集时,一个字符的存储空间可能是1到n个字节。
2.2 VARCHAR2
VARCHAR2类型用于存储变长的字符串,字段长度的取值范围是1到4000字节。VARCHAR2是变长的,这意味着实际存储长度与具体的字符串有关。
对于VARCHAR2类型的比较,Oracle不会预先填充空格,而是直接比较值。比如我们定义一个字段“TEST_VARCHAR2 VARCHAR2(2)”,插入对应字段值为“a ”的记录。当检索条件为“where TEST_ VARCHAR2=’a’”时是无法得到记录“a ”的。
另外,与CHAR一样,在定义VARCHAR2类型字段的最大长度时可以使用单位名称BYTE或CHAR,默认为BYTE。即“TEST_ VARCHAR2 VARCHAR2(2 BYTE)”意为最大长度为2个字节的VARCHAR2,而“TEST_ VARCHAR2 VARCHAR2 (2 CHAR)”意为长度为2个字符的VARCHAR2。
2.3 VARCHAR
在Oracle中,VARCHAR被定义为VARCHAR2的别名,其一切行为、特征与VARCHAR2相同。据传,起初,Oracle预留了VARCHAR字段类型用于与其他数据库兼容。而时至今日,它仍作为VARCHAR2的别名存在,其意义恐怕只是对Oracle数据库自身的向下兼容了。
2.4 NCHAR
NCHAR类型用于存储定长的Unicode字符串,其字符集只能是AL16UTF16或UTF8,与数据库安装时指定的字符集相同。有关Oracle数据库字符集的相关知识可参见Oracle官网在线文档Database Globalization Support Guide( https://docs.oracle.com/database/121/NLSPG/applocaledata.htm#NLSPG014)。
在设置NCHAR类型字段的长度时,不支持设置单位名称,即单位名称均为“字符”。比如“TEST_NCHAR NCHAR(2)”指长度为2个字符的NCHAR类型字段。NCHAR字段的最大长度是2000个字节。这意味着它最多可以存储2000个字符,但这些字符的实际存储空间不能超过2000个字节。
NCHAR的其他特性与CHAR相同,恕不赘述。
2.5 NVARCHAR2
NVARCHAR2类型用于存储变长的Unicode字符串,其特性参见VARCHAR2和NCHAR,恕不赘述。
2.6 CLOB
CLOB类型用于存储最大不超过128TB的变长字符串。CLOB支持事务,但不支持跨事务和会话的定位。下面的示例定义了一个叫做CLOB_TEST的CLOB类型的字段:CLOB_TEST CLOB。
因为CLOB类型的字段在表中记录的是实际信息的指针,因此无法在sql语句中使用比较运算符。如果我们需要查找CLOB_TEST值为“a”的记录可以使用查询条件“where dbms_lob.compare(t.clob_test,’a’)=0”。
2.7 NCLOB
NCLOB类型用于存储最大不超过128TB的Unicode变长字符串。NCLOB的其他特性与CLOB相同,恕不赘述。

3 字段类型选择依据

既然Oracle数据库提供了多种字段类型用于字符串类型数据的存储,那么我们在设计数据库表结构时应该如何选择呢?笔者认为应该从各字段类型的区别、限制入手,抓住字符串类型数据的关键特性,从而选择出最适合的字段类型。下面将逐一介绍这些关键特性。
3.1 最大长度
从存储信息的角度来说,字段支持的字符串长度是信息能否被完整保留的重要条件。CHAR和NCHAR的最大长度是2000字节,VARCHAR2和NVARCHAR2的最大长度是4000字节,CLOB和NCLOB的最大长度是128TB。当我们要选择一个字段类型来存储字符串信息时,应当首先根据业务模型判断字符串的最大值,排除掉无法满足最大存储需求的字段类型。因为CLOB(NCLOB)类型使用时的诸多不便,当CHAR(NCHAR)和VARCHAR2(NVARCHAR)字段类型的最大长度限制可以满足业务需求时,通常不使用CLOB(NCLOB)类型。
3.2 是否定长
CHAR(NCHAR)类型与VARCHAR2(NVARCHAR2)类型最大的区别在于是否定长。CHAR(NCHAR)类型是定长的,这意味着它拥有更高的访问效率。但是,当实际存储的信息小于设置的字段长度时,Oracle会用空格来填充,此时会浪费一定的存储空间。虽然对于单条记录这个影响可以忽略不计,但对于海量记录,这个浪费就需要引起足够的重视了。
VARCHAR2(NVARCHAR2)的情形与CHAR(NCHAR)刚好相反。它通过牺牲访问效率获得了更高的空间利用率。
3.3 存储内容包含的字符
NCHAR、NVARCHAR2、NCLOB类型存储Unicode字符串,仅支持AL16UTF16或UTF8字符集。虽然实际工作中很少遇到,但如果要存储的字符超出AL16UTF16和UTF8字符集范围,那就无法使用NCHAR、NVARCHAR2、NCLOB等字段类型了。
3.4 是否需要建立索引
如果需要为存储字符串的字段建立索引,那么我们要格外注意其对字段类型的限制。在CLOB和NCLOB类型的字段上是不能建立普通索引的。而在NCLOB类型的字段上是不能建立文本索引(如CONTEXT)的。
3.5 是否可能出现数据库迁移
如果可以预见在将来数据库可能发生迁移,那么设计数据库表结构时应该充分考虑字段类型的兼容性。比如,将Oracle中的NCHAR类型迁移到IBM DB2时,就需要通过CCSID子句创建兼容Unicode字符集的CHAR或VARCHAR。

4 常见场景的字段类型选择

第3节中从技术角度讨论了存储字符串类型数据时的选择依据,属于设计表结构时的一些指导原则。本节将以工作指导书的形式介绍在工作中经常涉及的几个业务场景中的字段类型选择及原因,帮助读者更深刻的理解各字段类型的差异。
4.1 记录状态及可枚举值
在数据库设计中,我们常常需要表示记录状态的字段。比如,用“R”表示记录已发布,“O”表示记录被检出;再比如用“O”表示树节点已展开,用“C”表示树节点已关闭;甚至表示布尔,用“1”表示真,用“0”表示假。
这类场景存储的字符串具有定长(或最大长度可知)、可枚举、信息通常为英文字母或数字、经常作为检索过滤条件等特点。
对于这类场景,我们通常使用CHAR类型字段进行存储。
4.2 GUID、UUID与MD5
GUID和UUID是我们经常使用的全局唯一标识符。它们具有长度、格式统一,字符可枚举(16进制数字)的特点。相应的,用于校验的MD5、SH-11、CRC等也有类似的特征。
对于这类字符串,我们通常使用CHAR类型字段来存储。
4.3 单据号、证件号
业务系统中经常需要存储符合一定格式的单据号、证件号。它们除了具有定长、字符可枚举的特点外,还是一些信息的编码集合。以身份证为例,18位数字中就包含了户籍地址、出生日期、性别、校验码等信息。因此,它们通常会被用于创建文本索引或函数索引。
对于单据号、证件号类型的字符串,我们通常使用CHAR类型字段来存储。
4.4 普通字符串
对于诸如“产品型号”、“产品规格”等一般业务属性字符串,通常符合变长、长度不超过4000字节的特征。
因此,我们可以使用VARCHAR2来存储这个类型的字符串。
4.5 静态页面、大文本
在一些web项目中,我们会将静态页面文件存储在数据库表中。一些基于诸如FreeMarker等模版引擎的项目也会将模版文件存储于数据库表中。另外,一些类似论坛、博客、新闻功能的应用也存在存储大量字符串的需求。
对于以上类型的需求,用排除法可知,能够几乎不受长度限制进行大文本存储的类型只有CLOB和NCLOB。当然,依前所述,我更倾向于使用CLOB。

Oracle数据库中字符串相关字段类型辨析相关推荐

  1. ef oracle 双引号,Oracle 数据库中字符串和日期必须使用双引号标识。

    Oracle 数据库中字符串和日期必须使用双引号标识. 更多相关问题 平面的投影规律是什么 下列有关生活给水管网水力计算的叙述中,错误的是( ). 下列______材料消耗不属于预算定额中材料必须消耗 ...

  2. oracle删除字段约束条件,Oracle 数据库中关于对表字段约束的操作(设置、删除、查询)...

    Oracle 数据库中关于对表字段约束的操作(设置.删除.查询) 1. 给表的单个字段加约束 SQL> ALTER TABLE 表名 ADD UNIQUE(字段名); 2. 删除表的单个字段约束 ...

  3. java向Oracle数据库中插入blob字段数据

    java不能直接想插入其他普通类型数据一样插入blob字段数据,因为blob相当于一个大文件块,里面有游标,需要初始化blob游标才能插入数据.所以我们要先插入一个空的blob数据,以初始化游标,然后 ...

  4. 往Oracle数据库中插入NCLOB/CLOB类型数据

    最近因为业务需求开发了一个接口用于接收数据,但是总有一些数据报出ORA-01704:字符串文字太长错误.仔细排查后发现,竟然是NCLOB类型字段提示这个错误.NCLOB存储空间有4G,怎么也想不明白为 ...

  5. oracle blob字段索引,在oracle 数据库中使用 Blob 字段存储 一张图片并读取

    1. 进行数据库的设置  create table image_lob(t_id varchar2(5) not null,t_image blob not null); create or repl ...

  6. mysql long raw_读取Oracle数据库中LONG RAW字段会抛出异常

    我使用Spring Boot + MyBatis + druid1.0.23读取表中的Long RAW字段时出现异常,然后我又使用Spring里的SingleConnectionDataSource能 ...

  7. oracle怎么截取long类型,Oracle 数据库中 Long 类型字段的读取

    最近在一个项目中遇到了需要读取 Oracle 数据库中的 Long 类型的字段的问题,折腾了好久,最后找到了其中的一个解决办法,决定记下了做个明灯吧! 在用 Mybatis 将该字段的数据映射到 St ...

  8. 存clob为空的值_给Oracle数据库中CLOB字段插入空值

    遇到往ORACLE数据库中插入数据时总是报ORA-01084 invalid argument in OCI call错误,经分析是因为表中的一个字段类型为CLOB,并且可为空,当在给该字段插入空值时 ...

  9. oracle时间24小时格式转换,在oracle数据库中查询时间并转为24小时制--------------String转Date类型或者Date转String类型...

    1.在Oracle数据库中查询时间的时候,首先就是把日期从date类型的转化为String类型的. 2.将date类型的转成String类型的,直接调用传入date类型的参数,返回String类型的字 ...

最新文章

  1. 【Codeforces】716B Complete the Word (26个字母)
  2. store下拉框同步_ExtJS下拉列表使用方法(异步传输数据)
  3. 火车头采集php源码不同,防火车头采集的功能
  4. 码代码,到白头|专访SRS创始作者阿里云RTC服务器团队负责人杨成立
  5. 华为云提供多场景本地数据上云方案,数据上云不再愁
  6. Matlab for Mac 中文路径乱码解决
  7. HDU3571 N-dimensional Sphere(高斯消元 同模方程)
  8. (一)PyQt5系列教程:使用PyQt5创建一个简单的demo
  9. 使用Python爬取百度热搜榜
  10. 崩溃,执行DELETE没加WHERE条件,该怎么办?
  11. 大数据应用场景有哪些?一篇文章告诉你
  12. game.php,game.php
  13. 【面试记录】1.给定一个由正数,负数和0组成的整数数组,将所有为0的元素,挪到数组末尾。2.给定任意一个自然数,获取它重新排列后,下一个比它大的自然数。(Leetcode 031 下一个排列)
  14. 网络错误 —未连接到互联网
  15. 【小程序】开发需要注意的地方(二)
  16. tp6+layui后台管理系统
  17. 如何搭建属于自己的腾讯云服务器
  18. android AP热点(wifi热点)开发
  19. 详解24个经典股票技术指标.doc
  20. MATLAB 相控阵雷达原理及仿真(雷达原理报告)

热门文章

  1. 微型计算机14年评测16万,多年以后重入16:10专业色彩级显示器,NEC EA245WMi开箱...
  2. paip.中国银联接口错误码总结
  3. Native.js 读写NFC数据
  4. Linux系统中将普通用户添加到sudoers
  5. APICS与AX的Master Planning(四)---Time Fence时限(时界)
  6. 使用GeoServer(GeoWebCache插件)发布ArcGIS切片地图
  7. Android telephony整体结构
  8. 让你认清楚JSP中的所有东西(java/JSP/EL/OGNL/JSTL/c标签/s标签/HTML/javascript/CSS)
  9. mysql连接池永驻_【学习笔记】Oracle连接池 数据库常驻连接池(Database Resident Connection Pool)案例介绍...
  10. 3ds Max 子物体的编辑