oracle数据库相信大家都比较熟悉,数据库中有一种非常常用的数据类型:字符串型。

         对应该类型,在oracle中有三种比较常用的类型:varchar2(byte)、varchar2(char)、nvarchar2()。

         那么这三种类型到底有什么区别呢?

         首先,我们要时刻记清:无论是varchar2还是nvarchar2,最大字节数都是4000

varchar2(byte):就是默认的表示方式,比如我们写成:varchar2(100),就相当于varchar2(100 byte),表示最大字节数是100,该字段最多能容纳100个字节,强调空间大小。由于我们描述的是字节,因此,保存汉字等字符时,就要小心了。如果你的数据库用的是GBK编码,那么一个汉字将占用2个字节,最多能存50个汉字,如果你的数据库用的是UTF8编码,那么一个汉字将占用3个字节,最多能存33个汉字。

varchar2(char):表示最大字符数是100,该字段最多能容纳100个字符,强调个数。假设我们写成varchar2(100 char),那么无论是数字、字母、汉字,都看成一个字符,最多写100个,当然,汉字越多,占用的空间越大,同样遵循上边的数据库编码原则。例如:存入一个汉字,底层占2或3个字节,存入一个字母,占1个字节,绝对不是某些文章所说1个字母或数字也占2或3个字节!

nvarchar2():没有byte、char之分,类似于varchar2(char),只不过nvarchar2()屏蔽了数据库编码,无论是何种编码,nvarchar2()中一个汉字都占两个字节。

         一般的教程,也就到这了,可是如果再多一步思考,会发现一个致命问题。

         实际应用中,很可能会出现这种写法:varchar2(1400 char),我们主观的认为,这个字段最长不能超过1400个字符,这意味着我们可能会存入1399个字符,貌似很正确的样子。

         但是,如果这1399个字符都是汉字,字符长度并没有超过1400,看起来一切正常,但实际上我们损失了一部分数据,为什么?

因为1399个汉字,按UTF8编码来说(99%的项目都是UTF8编码吧。。),需要占用1399*3=4197个字节,而文章开篇就说,无论是什么char,最大长度就是4000字节,一个也不能多,因此多出来的197个字节,都会抹去,而整个过程中,无任何错误提示,你的数据就这样蒸发了!

         所以,对于GBK编码的数据库而言,安全的写法为:varchar2(2000 char)、nvarchar2(2000),对于UTF8编码的数据库而言,安全的写法为:varchar2(1333 char)、nvarchar2(2000)。

PHP

PHP中,strlenmb_strlen是求字符串长度的函数,但是对于一些初学者来说,如果不看手册,也许不太清楚其中的区别。
下面通过例子,讲解这两者之间的区别。

先看例子:

  1. <?php 
  2. //测试时文件的编码方式要是UTF8 
  3. $str='中文a字1符'; 
  4. echo strlen($str).'<br>';//14 
  5. echo mb_strlen($str,'utf8').'<br>';//6 
  6. echo mb_strlen($str,'gbk').'<br>';//8 
  7. echo mb_strlen($str,'gb2312').'<br>';//10 
  8. ?>

结果分析:在strlen计算时,对待一个UTF8的中文字符是3个长度,所以“中文a字1符”长度是3*4+2=14,在mb_strlen计算时,选定内码为UTF8,则会将一个中文字符当作长度1来计算,所以“中文a字1符”长度是6 .

利用这两个函数则可以联合计算出一个中英文混排的串的占位是多少(一个中文字符的占位是2,英文字符是1)

  1. echo (strlen($str) + mb_strlen($str,'UTF8')) / 2;

例如 “中文a字1符” 的strlen($str)值是14,mb_strlen($str)值是6,则可以计算出“中文a字1符”的占位是10.

  1. echo mb_internal_encoding();

PHP内置的字符串长度函数strlen无法正确处理中文字符串,它得 到的只是字符串所占的字节数。对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是3倍的差异了(在 UTF-8编码下,一个汉字占3个字节)。

采用mb_strlen函数可以较好地解决这个问题。mb_strlen的用法和 strlen类似,只不过它有第二个可选参数用于指定字符编码。例如得到UTF-8的字符串$str长度,可以用 mb_strlen($str,'UTF-8')。如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过 mb_internal_encoding()函数得到。

需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函 数的问题。

Oracle Varchar2长度 及 PHP 长度判断的更多相关文章

  1. ORACLE VARCHAR2最大长度问题

    VARCHAR2数据类型的最大长度问题,是一个让人迷惑的问题,因为VARCHAR2既分PL/SQL Data Types中的变量类型,也分Oracle Database中的字段类型.简单的说,要看你在 ...

  2. Oracle varchar2最大支持长度(转)

    oerr ora 0650206502, 00000, "PL/SQL: numeric or value error%s"// *Cause: An arithmetic, nu ...

  3. Oracle修改字段类型和长度

    Oracle修改字段名 alter table 表名 rename column 旧字段名 to 新字段名 Oracle修改字段类型和长度 alter table 表名 modify 字段名 数据类型 ...

  4. Oracle改动字段类型和长度

    Oracle改动字段名 alter table 表名 rename column 旧字段名 to 新字段名 Oracle改动字段类型和长度 alter table 表名 modify 字段名 数据类型 ...

  5. java String长度与varchar长度匹配理解(字符和字节长度理解)

    java String长度与varchar长度匹配理解(字符和字节长度理解) string中的length()长度,返回的是char的数量,每个char可以存储世界上任何类型的文字和字符,一个char ...

  6. Oracle varchar2 4000

    关于oracle varchar2 官方文档的描述 VARCHAR2 Data Type The VARCHAR2 data type specifies a variable-length char ...

  7. Oracle删除表、字段之前判断表、字段是否存在

    这篇文章主要介绍了Oracle删除表.字段之前判断表.字段是否存在的相关资料,需要的朋友可以参考下 在Oracle中若删除一个不存在的表,如 “DROP TABLE tableName”,则会提示: ...

  8. SA密钥长度、明文长度和密文长度

    本文介绍RSA加解密中必须考虑到的密钥长度.明文长度和密文长度问题,对第一次接触RSA的开发人员来说,RSA算是比较复杂的算法,RSA的复杂度是因为数学家把效率和安全也考虑进去的缘故. 本文先只谈密钥 ...

  9. css控制文字长度,超出长度显示...

    css控制文字长度,超出长度显示... .style { max-width: 165px; overflow: hidden; white-space: nowrap; text-overflow: ...

  10. 限制标题字符串的长度,超过长度的截取并加上"..."

    /// <summary> /// 限制标题字符串的长度,超过长度的截取并加上"..." /// </summary> /// <param name ...

随机推荐

  1. 转载 asp.net中ViewState的用法详解

    转载原地址: http://www.jb51.net/article/73662.htm 在web窗体控件设置为runat = "server",这个控件会被附加一个隐藏的属性_V ...

  2. ASP.NET中配置应用程序

    1.   配置文件简介 1.1 分类 1.2关系 Machine.Config和Web.Config都是设置应用程序的配置信息,它们按照类似于继承的关系对应用程序起作用. Machine.Config ...

  3. 剑指OFFER之从二叉搜索树的后序遍历序列(九度OJ1367)

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...

  4. ECSHOP模板标签

    模板制作修改经常用到ecshop模板标签: 页面关键字 {$keywords }页面标题 {$page_title}产品分类父分类列表 {foreach from=$categories item=c ...

  5. C#-datagridview设置列宽

    在使用datagridview的显示数据的过程中,常常会遇到需要设定datagridview的列宽,这就需要用到datagridview的属性: autosizemode

  6. centos yum安装mysql

    查看有没有安装包 # yum list mysql 安装mysql客户端 # yum install mysql # yum list mysql-server 安装mysql 服务器端 # yum ...

  7. springMVC3学习(五)--MultiActionController

    Spring提供一个多动作控制器,使用它你能够将几个动作合并在一个控制器里,这样能够把功能组合在一起. 多动作控制器存在在一个单独的包中--org.springframework.web.mvc.mu ...

  8. main()函数的输入参数 main(int argc, char** argv)

    一般简单的C++程序,main函数的写法都是 int main() {... ; return 0;},但是,如果在运行程序时需要有参数输入,可以是使用将主函数写成int main(int argv, ...

  9. SQL Server 性能优化3 该指数(Index)保养

    前言 之前的一篇文章介绍了索引来提高数据库的查询性能,这其实仅仅是个开始.也许假设缺乏适当的保养,索引你以前建立的,甚至成为拖累,成为帮凶下降数据库的性能. 寻找碎片 消除碎片索引维护可能是最常规的任 ...

  10. Database API

    Database API Introduction Basic Usage Selects Joins Aggregates Raw Expressions Inserts Updates Delet ...