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

OracleDatabaseと文字コードについて

Avatar for sawaki.hideto sawaki.hideto
September 17, 2025

 OracleDatabaseと文字コードについて

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

Avatar for sawaki.hideto

sawaki.hideto

September 17, 2025

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」