なんですかねぇ、この基本的な標題。
というのも、GOLDホルダーであるこのワタクシ…
なんと
間違って覚えておりました!
Σ( ̄□ ̄)ガーン
VARCHAR2に全部空白(半角スペース)のデータを
追加できないなんて、
間違った認識を植え付けたのは誰だー!
(K泉さんかT須さんがあやしい)
よくよく考えたらそんなわけないもん。
何でこんな風に覚えてたんだろう…
そんなわけなので、
おさらいしてみましょう。
基本的な概念としては
CHAR → 固定長
VARCHAR2 → 可変長
ですね。
ここまではよいですね。
CHARは不足バイト分を半角スペースで埋めます。
VARCHAR2はもちろんそんなことせずに、入力したデータがそのまま格納されます。
以下を例にとって見てみましょう。
COL1はCHAR型なので、勝手にスペースが埋まっていますね。
それでは、今度はVARCHAR2にもスペースを付加してみます
(これすらできないと思い込んでいた…アホか)
結果はこうなります。
スペースを付加したら、そのデータが入力されました(当たり前)。
格納されるデータについてはこんなところですね。
それでは次に、これらのデータを検索する時の注意点です。
まず、以下の2つのセマンティクスがあることを覚えましょう。
①非空白埋め比較セマンティクス
比較する文字列のどちらかが(もしくはどちらも)VARCHAR2の場合
②空白埋め比較セマンティクス
比較する文字列のどちらもCHAR(またはリテラル)の場合
①の場合、半角スペースは見た目そのままの扱いで検索されます。
②の場合、半角スペースは無視されたように検索されます。
以上を踏まえて、
例を見てみましょう。(先程のデータを使うことにします)
まずは、①の場合。(VARCHAR2の比較)
上記の結果を見てわかる通り、半角スペースが認識されて検索しています。
次に、②の場合。(CHARの比較)
はい。どちらもHITしています。
半角スペースが無視されていることがわかりますね。
(こうしてみると、CHARに入っている半角スペースって
空気みたいなものだな~)
比較セマンティクスについては
こちらのサイトで詳しく説明されています↓
http://biz.rivus.jp/string_comparison_semantics.html
*ちなみに、上記サイトで
「'1' = '1 ' は成立するか?」
という検証を行なっています。
実際行なってみると、以下の結果となりました。
①SELECT '式は真です' x FROM DUAL WHERE '1' = '1 ' ; ○
②SELECT '式は真です' x FROM DUAL WHERE 1 = '1 ' ; ○
③SELECT '式は真です' x FROM DUAL WHERE 1 = ' 1' ; ○
④SELECT '式は真です' x FROM DUAL WHERE '1' = ' 1' ; ×
④の比較は無かったので、自分で検証してみました。
(結果は×)
そして次に、データ量・パフォーマンスについて。
データ量については
ORACLEMASTERの黒本を参照すると
「VARCHAR2→容量を節約できる」
と書いてあるのですが、
ネットで彷徨ったところ、いろんな意見が飛び交っておりまして
結局どの説が本当なのかわからずじまいですw
こちらなど参照↓
http://www.geocities.jp/kimura804/rdb/InterBase/ip_ib_strings_j.htm
まあ、スペース分節約できてるんだから
黒本が正しいのでしょう。
うん、そう考えよう(適当)
パフォーマンスですが、
これもネットで調べたところ
「CHARの方がパフォーマンスがよい」
という意見が多かったです。
なのでこれ採用(適当)。
たしかに、固定長の方が早そうだし。
そして最後に、
結局どちらを使うべきか?(というか使い分ける場合があるか)
そうですね、VARCHAR2を使っておきましよう。
こっちの方が推奨されているみたいですし。
本当に固定長のデータしか入らないのであれば
CHARでもいいと思いますけどね。
でもそんなにナーバスになる必要は
ないのではないかと。
とりあえず今回はこんな所です。
CHARとVARCHAR2の違いはわかりましたか?
みなさんも間違った知識をひけらかさないように
気をつけましょう!
(俺やっちゅーの)
というのも、GOLDホルダーであるこのワタクシ…
なんと
間違って覚えておりました!
Σ( ̄□ ̄)ガーン
VARCHAR2に全部空白(半角スペース)のデータを
追加できないなんて、
間違った認識を植え付けたのは誰だー!
(K泉さんかT須さんがあやしい)
よくよく考えたらそんなわけないもん。
何でこんな風に覚えてたんだろう…
そんなわけなので、
おさらいしてみましょう。
基本的な概念としては
CHAR → 固定長
VARCHAR2 → 可変長
ですね。
ここまではよいですね。
CHARは不足バイト分を半角スペースで埋めます。
VARCHAR2はもちろんそんなことせずに、入力したデータがそのまま格納されます。
以下を例にとって見てみましょう。
SQL> create table toritori(col1 char(5), col2 varchar2(5)); 表が作成されました。 SQL> desc toritori 名前 NULL? 型 ------------------- -------- ----------------- COL1 CHAR(5) COL2 VARCHAR2(5) SQL> insert into toritori values('TR1', 'TR2'); 1行が作成されました。 SQL> select '('||col1||')' col1 , '('||col2||')' col2 from toritori; COL1 COL2 ------- ------- (TR1 ) (TR2)
COL1はCHAR型なので、勝手にスペースが埋まっていますね。
それでは、今度はVARCHAR2にもスペースを付加してみます
(これすらできないと思い込んでいた…アホか)
SQL> update toritori set col2='TR2 '; 1行が更新されました。 SQL> select '('||col1||')' col1 , '('||col2||')' col2 from toritori; COL1 COL2 ------- ------- (TR1 ) (TR2 )
結果はこうなります。
スペースを付加したら、そのデータが入力されました(当たり前)。
格納されるデータについてはこんなところですね。
それでは次に、これらのデータを検索する時の注意点です。
まず、以下の2つのセマンティクスがあることを覚えましょう。
①非空白埋め比較セマンティクス
比較する文字列のどちらかが(もしくはどちらも)VARCHAR2の場合
②空白埋め比較セマンティクス
比較する文字列のどちらもCHAR(またはリテラル)の場合
①の場合、半角スペースは見た目そのままの扱いで検索されます。
②の場合、半角スペースは無視されたように検索されます。
以上を踏まえて、
例を見てみましょう。(先程のデータを使うことにします)
SQL> select '('||col1||')' col1 , '('||col2||')' col2 from toritori; COL1 COL2 ------- ------- (TR1 ) (TR2 )
まずは、①の場合。(VARCHAR2の比較)
SQL> select '('||col1||')' col1 , '('||col2||')' col2 from toritori 2 where col2='TR2'; レコードが選択されませんでした。 SQL> select '('||col1||')' col1 , '('||col2||')' col2 from toritori 2 where col2='TR2 '; COL1 COL2 ------- ------- (TR1 ) (TR2 )
上記の結果を見てわかる通り、半角スペースが認識されて検索しています。
次に、②の場合。(CHARの比較)
SQL> select '('||col1||')' col1 , '('||col2||')' col2 from toritori 2 where col1='TR1'; COL1 COL2 ------- ------- (TR1 ) (TR2 ) ↑これがHITしてしまう! SQL> select '('||col1||')' col1 , '('||col2||')' col2 from toritori 2 where col1='TR1 '; COL1 COL2 ------- ------- (TR1 ) (TR2 )
はい。どちらもHITしています。
半角スペースが無視されていることがわかりますね。
(こうしてみると、CHARに入っている半角スペースって
空気みたいなものだな~)
比較セマンティクスについては
こちらのサイトで詳しく説明されています↓
http://biz.rivus.jp/string_comparison_semantics.html
*ちなみに、上記サイトで
「'1' = '1 ' は成立するか?」
という検証を行なっています。
実際行なってみると、以下の結果となりました。
①SELECT '式は真です' x FROM DUAL WHERE '1' = '1 ' ; ○
②SELECT '式は真です' x FROM DUAL WHERE 1 = '1 ' ; ○
③SELECT '式は真です' x FROM DUAL WHERE 1 = ' 1' ; ○
④SELECT '式は真です' x FROM DUAL WHERE '1' = ' 1' ; ×
④の比較は無かったので、自分で検証してみました。
(結果は×)
そして次に、データ量・パフォーマンスについて。
データ量については
ORACLEMASTERの黒本を参照すると
「VARCHAR2→容量を節約できる」
と書いてあるのですが、
ネットで彷徨ったところ、いろんな意見が飛び交っておりまして
結局どの説が本当なのかわからずじまいですw
こちらなど参照↓
http://www.geocities.jp/kimura804/rdb/InterBase/ip_ib_strings_j.htm
まあ、スペース分節約できてるんだから
黒本が正しいのでしょう。
うん、そう考えよう(適当)
パフォーマンスですが、
これもネットで調べたところ
「CHARの方がパフォーマンスがよい」
という意見が多かったです。
なのでこれ採用(適当)。
たしかに、固定長の方が早そうだし。
そして最後に、
結局どちらを使うべきか?(というか使い分ける場合があるか)
そうですね、VARCHAR2を使っておきましよう。
こっちの方が推奨されているみたいですし。
本当に固定長のデータしか入らないのであれば
CHARでもいいと思いますけどね。
でもそんなにナーバスになる必要は
ないのではないかと。
とりあえず今回はこんな所です。
CHARとVARCHAR2の違いはわかりましたか?
みなさんも間違った知識をひけらかさないように
気をつけましょう!
(俺やっちゅーの)