Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OracleDatabaseと文字コードについて

 OracleDatabaseと文字コードについて

Oracle Database でのシステム更改時や、他システムからのデータ移行時に文字化けなど文字コードの問題に直面したことはありませんか?
例)AIX, HP-UX などでシフトJISベースの既存システムの更改時にLinux の UTF-8 ベースのシステムに移行
こういった場合の注意点をご紹介します。

Avatar for sawaki.hideto

sawaki.hideto

September 17, 2025
Tweet

More Decks by sawaki.hideto

Other Decks in Technology

Transcript

  1. Copyright (c) The Japan Research Institute, Limited 自己紹介 佐脇 秀登(SAWAKI

    Hideto) • 株式会社 日本総合研究所においてクレジットカードシステム(オープン系)開発を所管する本部の 部長(オンプレのOpenShift上に構築したAPIを提供するシステムや、一日数千万件のデータを扱う Oracle Exadata など、ミッションクリティカルで大規模なシステム基盤の責任者) • また、社内でシニアエキスパート(ITアーキテクト)としての職位に認定され、全社の大規模案件の アーキテクチャ検討支援を行うとともに、技術相談やログ解析などトラブルシューティング支援にも従事 • 本部内の新人研修も企画、運営 • 文字コードで痛い目にあってきた人 保有資格 • ORACLE MASTER Platinum 8i • 高度情報処理技術者試験 x 8 • ネットワークスペシャリスト • プロダクションエンジニア • データベーススペシャリスト • セキュリティ(今の情報処理安全確保支援士相当) • アプリケーションエンジニア(今のシステムアーキテクト相当) • プロジェクトマネージャ • ITサービスマネージャ • ITストラテジスト
  2. Copyright (c) The Japan Research Institute, Limited はじめに Oracle Databaseのシステム更改時や、他システムからのデータ移行時に文字化けや

    桁あふれなど、文字コードの問題に直面したことはありませんか? 例) ・AIX, HP-UX, Windows などでシフトJISをベースにしたシステムの更改時に Linux(RHEL, Oracle Linux) の UTF-8 ベースのシステムに移行する ・メインフレーム(IBM漢字コード)から Linux (UTF-8)にデータ移行する こういった場合のあるあるを言いたいです注意点をご紹介します。
  3. Copyright (c) The Japan Research Institute, Limited そもそも文字コードとは(1/2) コンピュータで文字を扱うための約束事 コンピュータは内部的にはバイナリデータ(ビット列)しか扱えないので、人間が使う文字との

    対応表が必要 バイナリデータと人が読む文字との対応表 例) 「あ」はShift_JISでは 82A0(16進数) ⇒ 符号化方式(エンコーディング) 「い」はShift_JISでは 82A2(16進数) ・ ・ ・ 「ん」はShift_JISでは 82F1(16進数) 文字集合
  4. Copyright (c) The Japan Research Institute, Limited そもそも文字コードとは(2/2) 文字コード =

    文字集合 + 符号化方式(エンコーディング) のように、2つの概念の組み合わせ 文字集合 = どの文字を扱えるか(ASCII, JIS X 0201, JIS X 0208, JIS X 0221 など) 例) ASCIIでは「1」「A」は含まれるが「カ」「カ」「漢」は含まれない JIS X 0201 というJIS規格では「1」「A」「カ」は含まれるが「カ」「漢」は含まれない (→Shift_JISで言う1Byte文字の集合) JIS X 0208 というJIS規格では「漢」という字が含まれており、コードポイントは20-33 符号化方式 = どうビット列に変換するか(Shift_JIS, EUC-JP, UTF-8, UTF-16など) 例) コードポイント20-33の文字(「漢」)はShift_JIS では16進数で8A BFに変換されるが、 UTF-8ではE6 BC A2、UTF-16では 6F 22に変換される Shift_JISなどの文字コードは複数の文字集合(JIS X 0201 と JIS X 0208など)を組み合わせ て符号化しています。
  5. Copyright (c) The Japan Research Institute, Limited あるある① • 設計書に「OracleデータベースのキャラクタセットはUTF8とする」と書いたら怒られました

    → ‘UTF8’ というキャラクタセットは古いので非推奨 (Unicode3.0以降の更新内容非対応 → 対応する文字が少ない、セキュリティ面の懸念も) → ‘AL32UTF8’ を使いましょう(Oracle社推奨) Oracle社公式サイト Unicodeを使用した多言語データベースのサポート より抜粋 (https://docs.oracle.com/cd/E96517_01/nlspg/supporting-multilingual-databases-with-unicode.html) • 「当然AL32UTF8に設定するつもりでしたが、略してUTF8と書いてしまいました」 → ‘UTF8’ というキャラクタセットが存在して紛らわしい 万が一間違って設定すると Oracle データベースのキャラクタセット変更は データベースの作り直し → 設計書には必ず正確に表記しましょう
  6. Copyright (c) The Japan Research Institute, Limited あるある② • 移行後にByte数が増えてデータベースのカラムの桁あふれを起こす

    my_char CHAR(10); -- JA16SJISなら漢字1文字2Byteなので5文字分 my_char := ‘辰吉丈一郎’; -- AL32UTF8 だと5文字でも15Byteで桁あふれになる ORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。 my_char CHAR(15); -- 漢字1文字3Byte分にしたら入った → 桁は拡張したけどストレージが不足することも → 見積り(サイジング)時点でだいたい何倍になりそうか分かっていないから
  7. Copyright (c) The Japan Research Institute, Limited 移行時のストレージ容量の概算見積り • かな、漢字(JIS

    X 0208)部分がJA16SJIS(TILDE)で2ByteからAL32UTF8で3Byteなので、 移行時のストレージ容量はざっくり1.5倍 • いわゆる半角英数のカラムが多ければ1:1でByte数は増加しないので、1.5倍より少し下がることも (経験則では1.2~1.3倍程度のストレージで足りることが多い) → ストレージ容量を節約したければ、何倍になる文字がどのぐらいの割合かを調べる 文字集合 例 JA16SJIS(TILDE) AL32UTF8 半角英数 JIS X 0201ラテン部分 1, A 1 1 半角カナ JIS X 0201カナ部分 カ 1 3 かな、漢字 (第一、第二水準) JIS X 0208 漢丈 2 3 機種依存文字 (IBM拡張、NEC特殊) Windows-31Jの ベンダー外字部分 髙① 2 3 サロゲートペア (第三、第四水準) JIS X 0213 𠀋𩸽 2 4 サロゲートペア (絵文字) JIS X 0221 の絵文字部分 非対応 4
  8. Copyright (c) The Japan Research Institute, Limited テーブルのカラムの桁数 テーブルのカラムの桁数については、どの文字集合が入りうるかに注意。 AL32UTF8では、いわゆる半角カナは3Byte、第三、第四水準漢字や顔文字は1文字4Byte。

    WindowsVISTA以降のMS IMEで入力は可能(=混入の恐れ※)※サロゲートペアの文字は 「環境依存」と表示される my_char CHAR(15); -- 漢字1文字3Byteと見積ったが… my_char := ‘辰吉𠀋一郎’; -- AL32UTF8 だと𠀋が4Byte、計16Byteで桁あふれになる ORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。 → 上流のアプリで入力制限しないなら、AL32UTF8での1文字は最大4Byteで見積る。 CHARではなく、VARCHAR2(20)なら末尾の空白埋めもないのでストレージ容量への影響は小さい 。 文字集合 例 JA16SJIS(TILDE) AL32UTF8 半角英数 JIS X 0201ラテン部分 1, A 1 1 半角カナ JIS X 0201カナ部分 カ 1 3 かな、漢字 (第一、第二水準) JIS X 0208 漢丈 2 3 機種依存文字 (IBM拡張、NEC特殊) Windows-31Jの ベンダー外字部分 髙① 2 3 サロゲートペア (第三、第四水準) JIS X 0213 𠀋𩸽 2 4 サロゲートペア (絵文字) JIS X 0221 の絵文字部分 非対応 4
  9. Copyright (c) The Japan Research Institute, Limited あるある③ 文字化けが起きるのはなぜ? •

    文字コードの不一致: 保存された文字コードと、表示しようとするシステムの文字コードが異なる場合に発生 • 文字コードの自動判別失敗: ブラウザやメールソフトが文字コードを自動判別する際に失敗 • デフォルト文字コードの設定ミス: ソフトウェアやシステムのデフォルトの文字コードが異なる場合、設定ミスが原因で文字化けする • 機種依存文字の使用: 機種依存文字は特定の環境でしか正しく表示されないため、異なる環境で文字化け • メールやウェブのエンコーディング指定ミス: メールやウェブページで正しいエンコーディングを指定していない場合、受信側で文字化け • 異なる言語設定: システムの言語設定が異なると、正しく表示されない • 文字エンコーディングの誤り: 例えば、UTF-8として保存されたファイルをShift_JISとして開くと文字化け • サーバとクライアントの設定不一致: サーバとクライアントの文字コード設定が一致していない場合に発生(Oracleは自動変換してくれる) • 規格のバージョン間の互換性: JIS規格などにもバージョン(JIS78, 83, 90, 2004)があり追加や字体の入れ替わりで文字化け 特に古いシステムやアプリケーションでは、新しい文字コードに対応していない → ややこしいから!(15分にまとめるのは無理でした!すみません!) その代わりに、文字のコード値を確認する Tips をいくつかご紹介しておきます
  10. Copyright (c) The Japan Research Institute, Limited (参考)Oracleデータベースで文字コードを見る方法 Q. カラムに入っている文字のコードを確認するために16進数ダンプ出力するにはどうしたら良いでしょうか

    A. dump 関数に 1016 の引数を与えて実行してください(16が16進数、1000がキャラクタセット表示) 実行例)name 列に「あ」が UTF-8(AL32UTF8) で格納されています(e3,81,82の3Byte) 残りは20(空白)で埋められていることが分かります。 文字化けする場合は「あ」などのデータを入れ、どの文字コードで符号化されているかを16進数ダンプで確認 すると調べやすいです。
  11. Copyright (c) The Japan Research Institute, Limited (参考)Linuxのファイルの文字のコードを確認する方法 Q. ファイルの文字のコードを確認するために16進数ダンプ出力するにはどうしたら良いでしょうか

    A. odコマンドを使います。-t x1 で1Byte単位に16進数で出力、zがつけば右にASCII文字が出ます。 実行例)「a」「改行」「あ」「改行」が UTF-8 で格納されています(「あ」はe3,81,82の3Byte) 文字コードを変換するには iconv の-fに変換元、-tに変換先を指定します。 例1)SJISの「a」と「改行」はUTF-8と同じ0x0a。「あ」は0x82a0の2Byte 例2)UTF-16はBOM(Byte Order Mark=エンディアン指定)の0xfffe(リトルエンディアン指定)の後、「a」は 0x6100、改行は0x0a、「あ」は「0x4230」。UnicodeのU+3042とはバイトの並びが逆になっている。 例3)CP930の「a」はEBCDICのため「0x62」、「改行」は「0x25」、IBM漢字への切り替えに「0x0e」、「あ」は「 0x4481」、EBCDICへ切り戻すのに「0x0f」