【问题标题】:What is the major difference between Varchar2 and charVarchar2和char之间的主要区别是什么
【发布时间】:2013-12-23 10:43:37
【问题描述】:

创建表:

CREATE TABLE test (
charcol    CHAR(10),
varcharcol VARCHAR2(10));

SELECT LENGTH(charcol), LENGTH(varcharcol) FROM test;

结果:

LENGTH(CHARCOL) LENGTH(VARCHARCOL)
--------------- ------------------
             10                  1 

请告诉我 Varchar2 和 char 有什么区别? 我们什么时候同时使用两者?

【问题讨论】:

    标签: sql oracle char varchar2


    【解决方案1】:

    虽然已经有几个答案正确描述了char的行为,但我认为有必要说你不应该使用它,除非在三种特定情况下:

    1. 您正在构建一个固定长度的文件或报告,并为char 分配一个非空值避免了编写rpad() 表达式的需要。例如,如果firstnamelastname 都定义为char(20),那么firstname || lastname 是写rpad(firstname,20) || rpad(lastname,20) 以创建Chuck Norris 的更短的方式。
    2. 您需要区分显式空字符串''null。通常它们在 Oracle 中是相同的,但是将 '' 分配给 char 值会触发其空白填充行为,而 null 不会,所以如果区分差异很重要,我真的想不出来是有原因的,那么你就有办法做到这一点。
    3. 您的代码是从某些其他系统移植而来(或需要与之兼容),这些系统出于遗留原因需要使用空白填充。在那种情况下,你会坚持下去,我很同情你。

    确实没有理由使用char,只是因为某些长度是固定的(例如Y/N 标志或ISO 货币代码,例如'USD')。它效率不高,不节省空间(varchar2 没有神话般的长度指示符,char 只有一个空白填充开销),并且它不会阻止任何人输入较短的值。 (如果您在char(3) 货币列中输入'ZZ',它将被存储为'ZZ '。)它甚至不能与曾经依赖它的某些古老版本的Oracle 向后兼容,因为从来没有。

    并且传染可以传播,因为(遵循最佳实践)您可以使用 sales.currency%type 之类的东西来锚定变量声明。现在您的l_sale_currency 变量是一个隐身char,对于较短的值(或''),它会以不可见的空白填充,从而为l_sale_currency 不等于l_refund_currency 的隐蔽错误打开了大门,即使您分配了@ 987654353@给他们俩。

    有些人认为char(n)(其中 n 是某个字符长度)表明值应该是 n 个字符长,这是一种自我-文档。但是,如果您认真对待 3 字符格式(例如,ISO-Alpha-3 国家代码而不是 ISO-Alpha-2),您肯定不会定义一个约束来强制执行规则,而不是让开发人员看一眼 char(3)数据类型并得出自己的结论?

    CHAR 在 Oracle 6 中被引入,我敢肯定,ANSI 兼容性的原因。可能有潜在客户决定购买哪种数据库产品,并且 ANSI 兼容性 在他们的清单上(或曾经在当时),并且在 ANSI 标准中定义了带有空白填充的CHAR,所以Oracle 需要提供它。你不应该实际使用它。

    【讨论】:

    • 这应该是最佳答案 - 特别是对于“你不应该实际使用它”!
    • +1 因为您的解释与 Tom Kyte 在 asktom.oracle.com 上的几个帖子相匹配:Char Vs VarcharShoud I use char or varchar2
    【解决方案2】:

    显示差异的简单示例:

    SELECT 
        '"'||CAST('abc' AS VARCHAR2(10))||'"', 
        '"'||CAST('abc' AS CHAR(10))||'"' 
    FROM dual;
    
    
    '"'||CAST('ABC'ASVARCHAR2(10))||'"' '"'||CAST('ABC'ASCHAR(10))||'"'
    ----------------------------------- -------------------------------
    "abc"                               "abc       "                   
    1 row selected.
    

    CHAR 对于字符长度始终固定的表达式很有用,例如美国各州的邮政编码,例如 CA、NY、FL、TX

    【讨论】:

    • CHAR 从来没有真正“有用”:美国州代码的存储效率与 VARCHAR2 一样。
    【解决方案3】:

    只是为了避免对许多错误信息造成混淆。以下是一些关于差异的信息,包括性能

    参考:https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2668391900346844476

    因为 char 只不过是一个 VARCHAR2,它是空白的 到最大长度 - 即列 X 之间的差异 和下面的 Y:

    创建表 t ( x varchar2(30), y char(30) );插入 t (x,y) 值( rpad('a',' ',30), 'a' );

    绝对没有,并且考虑到列 X 之间的差异 和下面的 Y:

    插入 t (x,y) 值 ('a','a')

    是X消耗3个字节(空指示符,前导字节长度,1 'a' 的字节)和 Y 消耗 32 个字节(空指示符,前导字节 长度,'a' 为 30 个字节)

    嗯,varchar2 将在某种程度上“处于优势表现” 明智的”。它完全没有帮助我们 char(30) 始终是 30 个字节 - 到 我们,它只是一个空白填充到最大值的 varchar2 长度。它可以帮助我们处理 - ZERO、zilch、zippo。

    任何时候你看到有人说“它快了 50%”,就是这样 - 没有例子,没有科学,没有事实,没有故事来支持它——只是笑 大声对他们说,继续前进。

    该页面上还有其他“虚构的东西”,例如:

    “在 CHAR 中搜索速度更快,因为所有字符串都存储在一个位置 相互指定位置,系统不必 搜索字符串的结尾。而在 VARCHAR 中,系统必须 先找到字符串的结尾,再去搜索。”

    FALSE:char 只是 varchar2 填充的空白 - 我们不存储 字符串“在彼此之间的指定位置”。我们确实搜索 字符串的结尾 - 我们使用前导字节长度来计算事物 出去。

    【讨论】:

      【解决方案4】:

      CHAR 类型是固定大小的,所以如果你说它是 10 个字节,那么它总是在数据库中存储 10 个字节,无论你存储任何文本还是只清空 10 个字节都没有关系

      VARCHAR2 大小取决于您实际要在数据库中存储的字节数。您指定的数字只是可以存储的最大字节数(尽管最小为 1 个字节)

      在处理固定长度的字符串时,您应该使用 CHAR(您事先知道要存储的字符串的确切长度) - 数据库可以更好更快地使用它,因为它知道确切的长度

      当您不知道存储字符串的确切长度时,您应该使用 VARCHAR2。

      你会同时使用的情况可能是:

      name VARCHAR2(255),
      zip_code CHAR(5) --if your users have only 5 place zip codes
      

      【讨论】:

      • 两者中哪一个更好用?
      • @ram:- 我认为没有人可以在不知道要求的情况下说哪个更好,因为根据要求,一个可能比另一个更好!
      • 你能用一个简单的解释一下吗?
      【解决方案5】:

      CHAR

      CHAR 应该用于存储固定长度的字符串。字符串值将在存储到磁盘之前填充空格/空白。如果用这种类型来存储变长字符串,会浪费很多磁盘空间。

      VARCHAR2

      VARCHAR2 用于存储变长字符串。字符串值的长度将与值本身一起存储在磁盘上。

      At what times we use both?
      

      这一切都取决于您的要求。

      【讨论】:

      • 大部分情况下我们同时使用
      【解决方案6】:

      当存储在数据库中时,varchar2 仅使用分配的空间。例如。如果你有一个 varchar2(1999) 并在表中放入 50 个字节,它将使用 52 个字节。

      但是当存储在数据库中时,char 总是使用最大长度并且是空白填充的。例如。如果你有 char(1999) 并在表中放入 50 个字节,它将消耗 2000 个字节。

      【讨论】:

        【解决方案7】:

        CHAR 用于存储固定长度的字符串。如果使用这种类型来存储可变长度的字符串,会浪费很多磁盘空间。

        VARCHAR2 用于存储变长字符串。

        我们什么时候同时使用两者?

        这可能会有所不同,具体取决于您的要求。

        编辑:-

        让我们通过一个例子来理解这一点,如果你有一个大小为 10 的学生姓名列; sname CHAR(10) 和如果插入列值'RAMA',则会在值的右侧插入6 个空格。如果这是一个 VARCHAR 列; sname VARCHAR2(10). 然后 Varchar 将在 10 个可能的空间中占用 4 个空格,并释放接下来的 6 个用于其他用途。

        【讨论】:

        • 主要在哪种情况下我们同时使用?
        • @ram:让我们通过一个例子来理解这一点,如果你有一个大小为 10 的学生姓名列; sname CHAR(10) 和如果插入列值“RAMA”,将在该值的右侧插入 6 个空格。如果这是一个 VARCHAR 列;名称 VARCHAR2(10)。然后 Varchar 将占用 10 个可能的空间中的 4 个,并释放接下来的 6 个用于其他用途。
        • 6 其他使用方式?
        • @ram:- 6 用于其他用途意味着剩余的内存可以被其他值使用:)
        猜你喜欢
        • 2011-05-29
        • 2015-08-22
        • 2015-08-06
        • 2011-03-06
        • 2017-04-28
        • 2011-04-14
        • 2010-09-17
        • 2021-11-30
        相关资源
        最近更新 更多