oracle Varchar2和char之间的主要区别是什么

kxe2p93d  于 2022-11-22  发布在  Oracle
关注(0)|答案(7)|浏览(234)
    • 正在 创建 表 : * *
CREATE TABLE test (
charcol    CHAR(10),
varcharcol VARCHAR2(10));

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

中 的 每 一 个

    • 结果 : * *
LENGTH(CHARCOL) LENGTH(VARCHARCOL)
--------------- ------------------
             10                  1

格式
请 让 我 知道 Varchar2 和 char 之间 的 区别 是 什么 ? 在 什么 时候 我们 都 使用 ?

jbose2ul

jbose2ul1#

虽然 已经 有 几 个 正确 描述 char 行为 的 答案 , 但 我 认为 需要 说明 的 是 , * * 您 不 应该 使用 它 * * , 除非 在 三 种 特定 情况 下 :
1.您 正在 建立 固定 长度 的 档案 或 报表 , 并 将 非 Null 值 指派 给 char , 可 避免 撰写 rpad() 运算 式 的 需求 。 例如 , 如果 firstnamelastname 都 定义 为 char(20) , 则 firstname||lastname 是 撰写 rpad(firstname,20)||rpad(lastname,20) 以 建立
Chuck Norris
1.您 需要 区分 显 式 空 字符 串 ''null 。 通常 , 它们 在 Oracle 中 是 相同 的 , 但是 将 '' 赋 给 char 值 将 触发 它 的 填充 空白 行为 , 而 null 不会 , 因此 , 如果 区分 它们 很 重要 , 而 我 真 的 想 不 出 为什么 会 这样 ,那 你 就 有 办法 了 。
1.你 的 代码 是 从 其他 一些 系统 移植 来 的 ( 或者 需要 兼容 ) , 这些 系统 由于 遗留 的 原因 需要 填充 空白 。 在 这种 情况 下 , 你 被 它 卡住 了 , 我 很 同情 你 。

    • 没有 理由 仅仅 因为 某些 长度 是 固定 的 就 使用 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 的 错误 打开 了 大门 , 即使 您 将 'ZZ' 分配 给 了 这 两 个 错误 。
有人 认为 char(n)( 其中 * n * 是 某 个 字符 长度 ) 表示 值 的 长度 应该 是 * n * 个 字符 , 这 是 一 种 自 文档 化 的 形式 。( 例如 , ISO-Alpha-3 国家/地区 代码 而 不是 ISO-Alpha-2 ) , 您 是否 应该 定义 一 个 约束 来 强制 执行 该 规则 ,而 不是 让 开发 人员 看 一眼 char(3) 数据 类型 并 得出 自己 的 结论 ?
我 确信 , Oracle 6 中 引入 CHAR 是 出于 ANSI 兼容 性 的 原因 。 可能 会 有 潜在 的 客户 决定 购买 哪 种 数据 库 产品 , 而 * ANSI 兼容 性 * 在 他们 的 清单 上 ( 或者 在 那时 曾经 是 ) , 并且 带有 空格 填充 的 CHAR 是 在 ANSI 标准 中 定义 的 , 因此 Oracle 需要 提供 它 。 您 不 应该 实际 使用 它 。

4ngedf3f

4ngedf3f2#

简单的例子来说明区别:

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)的邮政编码

liwlm1x9

liwlm1x93#

只是 为了 避免 混淆 许多 错误 的 信息 。 这里 有 一些 关于 差异 的 信息 , 包括 性能
参考 : https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2668391900346844476
由于 char 只 不过 是 一 个 VARCHAR2 , 它 用 空白 填充 到 最 大 长度 ( 即 下面 的 列 X 和 列 Y 之间 的 差 ) :
创建 表 t ( x 变量 字符 2 ( 30 ) , y 字符 ( 30 ) ) ;插入 t ( x , y ) 值 ( rpad ( " a " , " " , 30 ) , " a " ) ;
是 绝对 没有 , 并 考虑 到 列 X 和 Y 之间 的 差异 如下 :
插入 t ( x , y ) 值 ('a ' ,'a ' )
X 占用 3 个 字节 ( 空 指示 符 、 前导 字节 长度 、 1 个 字节 用于 " a " ) , Y 占用 32 个 字节 ( 空 指示 符 、 前导 字节 长度 、 30 个 字节 用于 " a " )
嗯 , varchar2 在 性能 方面 会 有 一些 优势 。 它 一 点 也 不 帮助 我们 char ( 30 ) 总是 30 个 字节 - 对 我们 来说 , 它 只是 一 个 varchar2 , 它 是 空白 填充 到 最 大 长度 。 它 帮助 我们 处理 - 零 , 零 , zippo 。
任何 时候 你 看到 任何 人 说 " 它 快 了 50% " , 就 是 这样 - 没有 例子 , 没有 科学 , 没有 事实 , 没有 故事 来 支持 它 - 只要 大声 嘲笑 他们 , 继续 前进 。
该 页面 上 还有 其他 " 虚构 的 内容 " , 例如 :

  • " 在 CHAR 中 搜索 速度 更 快 , 因为 所有 字符 串 都 存储 在 * * 彼此 之间 指定 的 位置 , 系统 不必 * * 搜索 字符 串 的 结尾 。 而 在 VARCHAR 中 , 系统 必须 * * 首先 找到 字符 串 的 结尾 , 然后 进行 搜索 。 " *

FALSE : 一 个 char 只是 一 个 varchar2 填充 的 空格 - - 我们 不会 将 字符 串 " 存储 在 彼此 之间 的 指定 位置 " 。 我们 会 搜索 字符 串 的 结尾 - - 我们 使用 前导 字节 长度 来 计算 。

bxpogfeg

bxpogfeg4#

字符

CHAR应该用于存储固定长度的字符串。字符串值在存储到磁盘之前将填充空格/空白。如果使用此类型存储可变长度的字符串,将浪费大量磁盘空间。

变量字符2

VARCHAR 2用于存储可变长度的字符串。字符串值的长度将与值本身一起存储在磁盘上。
"还有"

At what times we use both?

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

6qfn3psc

6qfn3psc5#

CHAR类型的大小是固定的,因此,如果您说它是10个字节,则它总是在数据库中存储10个字节,并且无论您是存储任何文本还是只存储空的10个字节都无关紧要
VARCHAR 2大小取决于您实际要在数据库中存储的字节数。您指定的数字只是可以存储的最大字节数(尽管1字节是最小值)

在处理固定长度的字符串(您事先知道要存储的字符串的确切长度)时,应该使用CHAR-数据库可以更好、更快地使用它进行操作,因为它知道确切的长度
如果不知道存储字符串的确切长度,则应使用VARCHAR 2。
在以下情况下,您可能会同时使用这两种方法:

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

vybvopom6#

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

mklgxw1f

mklgxw1f7#

    • CHAR * * 用于 存储 固定 长度 的 字符 串 。 如果 使用 此 类型 存储 可变 长度 的 字符 串 , 将 浪费 大量 磁盘 空间 。
    • VARCHAR2 * * 用于 存储 可变 长度 字符 串 。

什么 时候 我们 两 个 都 用 ?
这 可能 会 有所 不同 , 具体 取决 于 您 的 要求 。

    • 编辑 : - * *

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

相关问题