- 正在 创建 表 : * *
CREATE TABLE test (
charcol CHAR(10),
varcharcol VARCHAR2(10));
SELECT LENGTH(charcol), LENGTH(varcharcol) FROM test;
中 的 每 一 个
- 结果 : * *
LENGTH(CHARCOL) LENGTH(VARCHARCOL)
--------------- ------------------
10 1
格式
请 让 我 知道 Varchar2 和 char 之间 的 区别 是 什么 ? 在 什么 时候 我们 都 使用 ?
7条答案
按热度按时间jbose2ul1#
虽然 已经 有 几 个 正确 描述
char
行为 的 答案 , 但 我 认为 需要 说明 的 是 , * * 您 不 应该 使用 它 * * , 除非 在 三 种 特定 情况 下 :1.您 正在 建立 固定 长度 的 档案 或 报表 , 并 将 非 Null 值 指派 给
char
, 可 避免 撰写rpad()
运算 式 的 需求 。 例如 , 如果firstname
和lastname
都 定义 为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 需要 提供 它 。 您 不 应该 实际 使用 它 。4ngedf3f2#
简单的例子来说明区别:
CHAR用于字符长度始终固定的表达式,例如,美国各州(如CA、NY、FL、TX)的邮政编码
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% " , 就 是 这样 - 没有 例子 , 没有 科学 , 没有 事实 , 没有 故事 来 支持 它 - 只要 大声 嘲笑 他们 , 继续 前进 。
该 页面 上 还有 其他 " 虚构 的 内容 " , 例如 :
FALSE : 一 个 char 只是 一 个 varchar2 填充 的 空格 - - 我们 不会 将 字符 串 " 存储 在 彼此 之间 的 指定 位置 " 。 我们 会 搜索 字符 串 的 结尾 - - 我们 使用 前导 字节 长度 来 计算 。
bxpogfeg4#
字符
CHAR应该用于存储固定长度的字符串。字符串值在存储到磁盘之前将填充空格/空白。如果使用此类型存储可变长度的字符串,将浪费大量磁盘空间。
变量字符2
VARCHAR 2用于存储可变长度的字符串。字符串值的长度将与值本身一起存储在磁盘上。
"还有"
这一切都取决于你的要求。
6qfn3psc5#
CHAR类型的大小是固定的,因此,如果您说它是10个字节,则它总是在数据库中存储10个字节,并且无论您是存储任何文本还是只存储空的10个字节都无关紧要
VARCHAR 2大小取决于您实际要在数据库中存储的字节数。您指定的数字只是可以存储的最大字节数(尽管1字节是最小值)
在处理固定长度的字符串(您事先知道要存储的字符串的确切长度)时,应该使用CHAR-数据库可以更好、更快地使用它进行操作,因为它知道确切的长度
如果不知道存储字符串的确切长度,则应使用VARCHAR 2。
在以下情况下,您可能会同时使用这两种方法:
vybvopom6#
当存储在数据库中时,varchar2只使用分配的空间。例如,如果您有一个varchar2(1999),并在表中放入50个字节,它将使用52个字节。
但是当存储在数据库中时,char总是使用最大长度并填充空白。例如,如果你有char(1999)并在表中放入50个字节,它将消耗2000个字节。
mklgxw1f7#
什么 时候 我们 两 个 都 用 ?
这 可能 会 有所 不同 , 具体 取决 于 您 的 要求 。
让 我们 通过 一 个 例子 来 理解 这 一 点 , 如果 你 有 一 个 学生 姓名 列 , 大小 为 10 ; sname
CHAR(10)
和 如果 插入 了 列 值'RAMA'
, 则 会 在 该 值 的 右侧 插入 * * 6 个 空格 * * 。 如果 这 是 VARCHAR 列 ; snameVARCHAR2(10).
然后 Varchar 将 从 10 个 可能 的 空间 中 取出 4 个 , 并 释放 接下来 的 6 个 空间 用于 其他 用途 。