11 文字セットの移行
この章では、文字セット変換と文字セットの移行について説明します。この章の内容は次のとおりです。
11.1 文字セットの移行の概要
使用しているデータベースに適切な文字セットを選択することは、重要な決定事項です。データベース文字セットの選択時には、次の要因を考慮する必要があります。
-
格納する必要があるデータの型
-
データベースで現在および将来対応する必要のある言語
-
各文字セットの異なるサイズ要件とその要件がパフォーマンスに与える影響
国際的な汎用性を維持し、最新技術や今後の技術、言語の要件に合せるためにUnicodeを選択することをお薦めします。Unicode規格で規定されている文字セットは、使用頻度が高い最近の書き言葉にも、めったに使用されない古い文字にもすべて対応しています。また、技術分野、科学分野、音楽表記などの各種の記号にも対応しています。Java、Windows、HTML、XMLなどの各種技術に固有の文字セットであり、また推奨の文字セットです。このような汎用文字セットは他にありません。さらに、Unicodeは工業分野で大きな支持を受けており、採用する動きが急速に広まっています。
AL32UTF8はOracleが実装したUnicodeであり、ASCII文字の文字コードを1バイト、欧州系の文字と中東地方の言語を2バイト、東南アジア系の言語を3バイトで表現します。したがって、Unicodeの保存に必要な領域は通常、同じ言語で比較した場合に、従来の文字セットの必要領域よりも多くなります。
関連するトピックとして、既存のデータベース用の新規文字セットの選択があります。既存のデータベース用のデータベース文字セットを変更することを、文字セットの移行と呼びます。この場合でも、汎用性と互換性を維持するためにUnicodeに移行することをお薦めします。データベース文字セット間の移行を行う際に、次の要因によるデータの損失を最小限に抑えるようにする必要もあります。
-
関連項目:
11.1.1 データの切捨て
データベースがバイト・セマンティクスを使用して作成されている場合、CHAR
およびVARCHAR2
データ型のサイズは、文字単位ではなくバイト単位で指定されます。たとえば、表定義でCHAR(20)
と指定すると、文字データを格納するために20バイトが割り当てられます。データベース文字セットでシングルバイト文字コード体系が使用されている場合は、文字数がバイト数と同じであるため、文字の格納時にデータ消失は発生しません。データベース文字セットでマルチバイト文字セットが使用されている場合は、1文字が1バイト以上で構成される場合があるため、バイト数は文字数とは異なります。
新規文字セットへの移行時には、既存のCHAR
およびVARCHAR2
列の列幅を検証することが重要です。これは、マルチバイトを格納する必要があるエンコーディングをサポートするために、列幅の拡張が必要となる場合があるためです。変換によってデータが拡張されると、データが切り捨てられる可能性があります。
次の表に、変換を通じてシングルバイト文字がマルチバイト文字になる場合のデータ拡張例を示します。
表11-1 シングルバイトとマルチバイトのエンコーディング
文字 | WE8MSWIN 1252エンコーディング | AL32UTF8エンコーディング |
---|---|---|
ä |
E4 |
C3 A4 |
ö |
F6 |
C3 B6 |
© |
A9 |
C2 A9 |
€ |
80 |
E2 82 AC |
前の表の1列目は選択した文字、2列目はWE8MSWIN1252文字セットでの文字の16進表現、3列目はAL32UTF8文字セットでの各文字の16進表現を示します。文字と数字のペアは、それぞれ1バイトを表します。たとえば、ä
(ウムラウト付きのa
)は、WE8MSWIN1252のシングルバイト文字(E4
)ですが、AL32UTF8では、2バイト文字(C3 A4
)になります。また、ユーロ記号のエンコーディングは1バイト(80
)から3バイト(E2 82 AC
)に拡張されます。
新しい文字セットのデータにデータ型でサポートされるバイト・サイズより大きい記憶域が必要な場合は、スキーマを変更する必要があります。CLOB
列の使用が必要になる場合があります。
関連項目:
11.1.1.1 データの切捨てによって生じるその他の問題
-
データベース・データ・ディクショナリ内でのスキーマ・オブジェクト名は、30バイトを超えることはできません。スキーマ・オブジェクト名が新規データベース文字セットで30バイトを超える場合は、そのオブジェクト名を変更する必要があります。たとえば、タイ語の各国語文字セットではタイ語1文字に1バイト必要です。一方、AL32UTF8では3バイト必要です。タイ語11文字の名前を持つ表を定義している場合、データベース文字セットをAL32UTF8に変更するときは、この表名を10文字以下に短縮する必要があります。
-
既存のOracleユーザー名またはパスワードが文字ベースで作成されており、その内容が変換先の文字セットでサイズ変更された場合、新規文字セットへの移行後は認証がエラーとなるため、ユーザーのログイン時に問題が発生します。この問題が発生するのは、データ・ディクショナリに格納されている暗号化されたユーザー名とパスワードを、新規文字セットへの移行時に更新できないためです。たとえば、現行のデータベース文字セットがWE8MSWIN1252で、変換先のデータベース文字セットがAL32UTF8の場合、ユーザー名
scött
(ウムラウト付きのo
)の長さは5バイトから6バイトに変更されます。AL32UTF8では、ユーザー名が異なるため、scött
はログインできなくなります。ユーザー名とパスワードにはASCII文字を使用することをお薦めします。ASCII文字以外の場合は、新規文字セットへの移行後に、影響のあるユーザー名とパスワードを再設定する必要があります。 -
CHAR
データに、新規文字セットへの移行後に拡張される文字が含まれている場合、デフォルトでは、データベースのエクスポート時に空白埋込みは削除されません。つまり、これらの行は、新規文字セットでデータベースにインポートされるときに拒否されます。これを回避するには、CHAR
データをインポートする前にBLANK_TRIMMING
初期化パラメータをTRUE
に設定します。関連項目:
BLANK_TRIMMING初期化パラメータの詳細は、『Oracle Databaseリファレンス』
を参照してください。
11.1.2 文字セット変換の問題
この項には次のトピックが含まれます:
11.1.2.1 エクスポート・ユーティリティとインポート・ユーティリティの使用による置換文字
エクスポート・ユーティリティとインポート・ユーティリティでは、オリジナルのデータベース文字セットから新規のデータベース文字セットに文字セットを変換できます。ただし、文字セット変換によって、データが消失したり、破損する可能性があります。たとえば、文字セットAから文字セットBに移行する場合に、変換先文字セットトBは文字セットAのスーパーセットであることが必要です。変換先文字セットBは、文字セットAで定義されているすべての文字を含む場合に、スーパーセットになります。文字セットBで使用できない文字は、置換文字に変換されます。この置換文字は、通常、?
または¿
として指定されるか、使用不可能な文字に関連する1文字として指定されます。たとえば、ä
(ウムラウト付きのa
)はa
で変換できます。置換文字は、変換先文字セットで定義されます。
ノート:
変換先文字セットBは、文字セットAのスーパーセットであることが必要という必要条件に対して例外があります。文字セットAに含まれるが、文字セットBに含まれない文字がデータの中に入っていなければ、データ消失またはデータ破損を防ぐために、変換先文字セットが文字セットAのスーパーセットである必要はありません。
次の図に、著作権記号とユーロ記号が?
に変換され、ä
がa
に変換される文字セット変換の例を示します。
データ消失のリスクを削減するには、類似する文字レパートリを持つ文字セットを変換先に選択してください。AL32UTF8には既存の文字セットのほとんどの文字が含まれているため、Unicodeへの移行は最もよい選択肢である可能性があります。
11.1.2.2 クライアントのNLS_LANGパラメータ設定が不適切であるために生じる無効なデータ
データ消失の可能性がある文字セット移行の使用例として、無効なデータを含むデータベースの移行が考えられます。NLS_LANG
パラメータがクライアント上で適切に設定されていないため、通常は、データベースに無効なデータが含まれます。NLS_LANG
値には、クライアント・オペレーティング・システム・コード・ページを反映する必要があります。たとえば、英語版Windows環境では、コード・ページはWE8MSWIN1252です。NLS_LANG
パラメータを適切に設定すると、データベースはクライアント・オペレーティング・システムからのデータを自動的に変換できます。NLS_LANG
パラメータが適切に設定されていないと、データベースに入ってくるデータは適切に変換されません。たとえば、データベース文字セットがAL32UTF8で、クライアントが英語版Windowsオペレーティング・システムで、クライアント上でのNLS_LANG
設定がAL32UTF8であるとします。データベースに入ってくるデータはWE8MSWIN1252でエンコードされており、クライアント上のNLS_LANG
設定がデータベース文字セットと一致するため、AL32UTF8データには変換されません。そのため、Oracleでは変換は不要であるとみなされ、データベースに無効なデータが入力されます。
この結果、データの非一貫性の問題が2つ発生する可能性があります。一方の問題が発生するのは、データベースに含まれているデータの文字セットがデータベース文字セットとは異なっているが、両方の文字セットに同じコード・ポイントが存在する場合です。たとえば、データベース文字セットがWE8ISO8859P1で、中国語版Windows NTクライアントのNLS_LANG
設定がSIMPLIFIED CHINESE_CHINA.WE8ISO8859P1の場合、(ZHS16GBK文字セットの)すべてのマルチバイトの中国語データは、シングルバイトWE8ISO8859P1データの倍数として格納されます。これは、Oracleではこれらの文字がシングルバイトWE8ISO8859P1文字として処理されることを意味します。そのため、SUBSTRやLENGTHなどのSQL文字列操作関数はすべて、文字ではなくバイトを基準にして処理されます。ZHS16GBKデータを構成するすべてのバイトは、有効なWE8ISO8859P1コードです。このようなデータベースをAL32UTF8などの別の文字セットに移行する場合、文字コードは、WE8ISO8859P1内の文字コードと同様に変換されます。このように、ZHS16GBK文字の2バイトはそれぞれ個別に変換され、AL32UTF8では意味のない値になります。次の図に、この不適切な文字セット置換の例を示します。
2つ目の問題は、混在する文字セットのデータがデータベースにある場合です。たとえば、データ文字セットがWE8MSWIN1252で、ドイツ語とギリシャ語を使用している2つの別々のWindowsクライアントがともに、NLS_LANG
文字セットとしてWE8MSWIN1252を使用している場合、データベースにはドイツ語とギリシャ語の文字が混在することになります。次の図に、異なるクライアントが、同一データベースの異なる文字セットを使用する方法を示します。
データベース文字セットの移行を適切に行うには、この2つの状況の場合、手作業による調整が必要です。これは、Oracle Databaseでは格納されているデータの文字セットを判断できないためです。不適切なデータ変換はデータを破損する恐れがあるため、新規文字セットにデータを移行する前に、データベース全体のバックアップを作成します。Database Migration Assistant for Unicode (DMU)ソフトウェアを使用した、Unicodeへの文字セット移行時の不適切な文字データの処理の詳細は、「既存のデータベースのデータベース文字セットの変更」を参照してください。
11.2 既存のデータベースのデータベース文字セットの変更
データベース文字セットの移行は、通常、データ・スキャニング、データ・クレンジング、およびデータ変換の3段階からなる複雑なプロセスになります。
データベース文字セットを変更する前に、考えられるデータベース文字セット変換の問題とデータの切捨てを識別する必要があります。このステップはデータ・スキャニングと呼ばれます。データ・スキャニングによって、データベース文字セットの変更前に、データを新しい文字コード体系に移行するために必要な作業量が識別されます。データ・スキャニング時に検出される例には、列幅の拡張が必要なスキーマ・オブジェクトの数や、変換先の文字レパートリに存在しないデータの分布などがあります。この情報は、データベース文字セットの最適な変換方法の決定に役立ちます。
データの潜在的な問題を特定したら、データ変換時にデータの整合性を保持するために、データをクレンジングする必要があります。検出されたデータの問題の大きさや複雑さによっては、データ・クレンジングの作業にかかる時間と手間が大きくなる可能性があります。データ例外をすべて適切に対処するために、データ・スキャニングとデータ・クレンジングを何回も繰り返す場合があります。
データ変換は、文字データを変換元の文字セットから変換先の文字セット表現に変換するプロセスです。不適切なデータ変換はデータを破損する恐れがあるため、新規文字セットにデータを移行する前に、データベース全体のバックアップを作成します。
11.2.1 Database Migration Assistant for Unicodeを使用した文字データの移行
Database Migration Assistant for Unicode(DMU)は、直感的な操作が可能な、ユーザーに親しみやすいGUIを装備しており、そのインタフェースを介して手作業による手間を大幅に減らし、移行作業を正確かつ効率よく実行して、Unicodeに効率よく移行できるようになっています。
DMUの利点は次のとおりです。
-
ワークフローが順を追って説明されます。
DMUの大きな利点は、論理的なワークフローによって文字セット移行プロセス全体が順を追って説明されることです。
-
特定の問題に対処するための推奨方法が示されます。
データ・スキャニングやデータ・クレンジングの実行中にエラーや障害などの問題が発生した場合に、DMUはユーザーを支援します。
-
データの選択的変換がサポートされています。
DMUは、変換が必要なデータのみに絞って、表レベル、列レベル、および行レベルでデータを変換できます。
-
進行状況モニターが提供されます
DMUは、処理の進行状況をわかりやすく表示するGUIを備えています。
-
対話的な表示機能が提供されます。
DMUにより、対話型のGUIを介してデータの分析と結果の確認を行うことができます。また、GUIでデータそのものを確認して、特定された移行問題のあるデータを対話形式でクレンジングできます。
-
インライン変換専用にサポートされたツールが提供されます。
DMUを使用すると、Oracle Databaseでデータベースの内容のインライン変換がサポートされます。これは、パフォーマンスおよびセキュリティに関して、他の既存の変換方法よりも優れています。
-
変換ステップ中に、クレンジング・アクションを後で実行するようにスケジュールできます。
データ型の移行などのクレンジングの処理を後に回せば、実際に移行を行う停止期間に入るまでは、本番用のデータベースとアプリケーションは移行の影響を受けずに済みます。
このリリースのDatabase Migration Assistant for Unicodeには、変換できるデータベースについて、いくつかの制約があります。特に、データ・ディクショナリ内に特定のタイプの変換可能データがあるデータベースを変換しません。エクスポート/インポート移行方式を使用すれば、このような制限事項を解消できます。
現在のデータベース・リリースでは、DMUは$ORACLE_HOME/dmu
ディレクトリにインストールされます。
11.2.2 全体エクスポートおよび全体インポートを使用した文字データの移行
全体エクスポートと全体インポートは、データベースを新しい文字セットに変換する際にも使用できます。別々のターゲット・インスタンスを設定する必要があるため、時間も長くかかり、リソースも大量に必要になる場合があります。データをUnicode以外の文字セットに移行する場合は、あまりお薦めできませんが、DMUを使用して、データベース内に無効な文字表現がないかどうかを調べてから、データ変換にエクスポートとインポートを使用することは可能です。Unicodeに移行しない場合は、データのサイズ超過の問題(列およびデータ型の制限に対する違反)をDMUが正確には検出しないことに注意してください。また、ソースのデータベース文字セットにはあっても、ターゲットのUnicode以外の文字セットにはない文字を識別しません。
関連項目:
エクスポート・ユーティリティとインポート・ユーティリティの詳細は、『Oracle Databaseユーティリティ』 を参照してください
11.3 データベース文字セット・メタデータの修復
データベースが、一般的にパススルー構成と呼ばれる構成になっていて、クライアントの文字セットがデータベース文字セットと同じになるように定義されている(通常はNLS_LANG
クライアント設定になっている)場合は、データベースの文字データが、宣言されているデータベース文字セットとは異なる文字セットで格納されている可能性があります。このシナリオにおいて推奨される解決策は、DMUの想定データベース文字セット機能でデータの実際の文字セットを指定して、データベースをUnicodeに移行することです。業務上または技術上の制約によってUnicodeへの移行をすぐには実行できない場合も、少なくとも、データベースの内容と一致するようにデータベース文字セット宣言を修正することをお薦めします。
そのような場合、Database Migration Assistant for Unicodeリリース1.2では、CSREPAIR
スクリプトを使用してデータベース文字セット・メタデータを修復できます。CSREPAIR
スクリプトはDMUクライアントと連携して動作し、DMUリポジトリにアクセスします。DMUで想定データベース文字セット・プロパティをターゲット文字セットに設定して全体データベース・スキャンを実行し、無効な表現の問題が報告されなくなると、データベース内のすべての既存データが想定データベース文字セットに従って定義されていることが確認されるため、その後でこれを使用してデータベース文字セット宣言をデータの実際の文字セットに変更してください。CSREPAIR
により変更されるのはデータ・ディクショナリ・メタデータ内のデータベース文字セット宣言のみであり、データベース・データは変換されないことに注意してください。
CSREPAIR
スクリプトは、インストールされたDMUのadmin
サブディレクトリにあります。CSREPAIR
スクリプトを使用する際の要件は次のとおりです。
- まず、DMUで想定データベース文字セット・プロパティをデータの実際の文字セットに設定して、全体データベース・スキャンを正常に完了する必要があります。この場合、想定データベース文字セットは現在のデータベース文字セットと異なる必要があり、そうでない場合は何も行われません。DMUが無効なデータの存在を報告する場合は、
CSREPAIR
スクリプトの処理が中断されます。ただし、スキャンで、変更不要データまたは変換可能なデータが検出された場合は処理が継続されます。 - 想定データベース文字セットのターゲット文字セットは、US7ASCIIのバイナリ・スーパーセットである必要があります。
- シングルバイト文字セットからシングルバイト文字セットへの修復、またはマルチバイト文字セットからマルチバイト文字セットへの修復のみが、
CLOB
データの変換が試行されないために許可されます。 - 想定文字セットを列レベルで設定する場合、値は想定データベース文字セットと同じである必要があります。そうでない場合、
CSREPAIR
は実行されません。 CSREPAIR
を実行するには、SYSDBA
権限が必要です。
11.4 Language and Character Set File Scanner
Language and Character Set File Scanner(LCSSCAN
)は、統計に基づく高パフォーマンスのユーティリティであり、不明なファイル・テキストの言語と文字セットを判別します。様々な言語と文字セットのペアを自動的に識別できます。言語および文字セット検出エンジンでは、各テキストを使用して一連の確率が設定され、各確率は1つの言語および文字セットのペアに対応します。統計的に最も可能性の高いペアにより、主要な言語と文字セットが識別されます。
テキストの純粋性は、言語および文字セット検出の正確さに影響します。理想的なケースは、スペルや構文の誤りのない単一言語による文章です。この種のテキストには100文字以上のデータを必要とする場合があり、信頼率の高い結果を戻すことができます。これに対して、ある種の技術文書は、より長いセグメントにしなければ認識されない場合があります。ドキュメントに複数の言語や文字セット、住所、電話番号などのテキストまたはプログラミング言語コードが混在していると、適切な結果が得られない可能性があります。たとえば、ドキュメントにフランス語とドイツ語の両方が埋め込まれていると、どちらかの言語が正常に推測される精度は統計的に減少します。プレーン・テキストとHTMLの両方のファイルが受け入れられます。書式が判明している場合は、精度を上げるためにFORMAT
パラメータを設定する必要があります。
この項には次のトピックが含まれます:
11.4.1 LCSSCANコマンドの構文
Language and Character Set File Scannerを起動するには、LCSSCAN
コマンドを使用します。構文は次のとおりです。
LCSSCAN [RESULTS=number] [FORMAT=file_type] [BEGIN=number] [END=number] FILE=file_name
ここでは、各パラメータについて説明します。
RESULTS
プロパティ | 説明 |
---|---|
デフォルト値 |
|
最小値 |
|
最大値 |
|
目的 |
戻される言語と文字セットのペアの数。確率順に表示されます。最初の選択肢の比較重量は定量化できません。このパラメータの推奨値は、デフォルト値 |
FORMAT
FORMAT
パラメータの指定は任意です。
プロパティ | 説明 |
---|---|
デフォルト値 |
|
目的 |
スキャン対象となるファイルのタイプを識別します。可能な値は、 |
BEGIN
プロパティ | 説明 |
---|---|
デフォルト値 |
|
最小値 |
|
最大値 |
ファイルのバイト数 |
目的 |
入力ファイル内で |
END
プロパティ | 説明 |
---|---|
デフォルト値 |
ファイルの終わり |
最小値 |
|
最大値 |
ファイルのバイト数 |
目的 |
入力ファイル内で |
FILE
プロパティ | 説明 |
---|---|
デフォルト値 |
なし |
目的 |
スキャン対象となるテキスト・ファイルの名前を指定します。 |
11.4.2 例: LCSSCANコマンドの使用
例11-1 LCSSCANコマンドでファイル名のみを指定する例
LCSSCAN FILE=example.txt
この例では、BEGIN
およびEND
パラメータがどちらも指定されていないため、example.txt
ファイル全体がスキャンされます。RESULTS
パラメータが指定されていないため、言語と文字セットのペアが1つ戻されます。
例11-2 書式をHTMLに指定する例
LCSSCAN FILE=example.html FORMAT=html
この例では、BEGIN
およびEND
パラメータがどちらも指定されていないため、example.html
ファイル全体がスキャンされます。このスキャンでは、スキャンする前にHTMLタグが取り除かれるため、より正確な結果を得られます。RESULTS
パラメータが指定されていないため、言語と文字セットのペアが1つ戻されます。
例11-3 LCSSCANに対してRESULTSおよびBEGINパラメータを指定する例
LCSSCAN RESULTS=2 BEGIN=50 FILE=example.txt
スキャン処理はファイルの50バイト目から始まり、ファイルの終わりまで続行されます。言語と文字セットのペアが2つ戻されます。
例11-4 LCSSCANに対してRESULTSおよびENDパラメータを指定する例
LCSSCAN RESULTS=3 END=100 FILE=example.txt
スキャン処理はファイルの先頭から始まり、ファイルの100バイト目で終了します。言語と文字セットのペアが3つ戻されます。
例11-5 LCSSCANに対してBEGINおよびENDパラメータを指定する例
LCSSCAN BEGIN=50 END=100 FILE=example.txt
スキャン処理はファイルの50バイト目から始まり、ファイルの100バイト目で終了します。RESULTS
パラメータが指定されていないため、言語と文字セットのペアが1つ戻されます。
11.4.4 サポート対象の言語と文字セット
Language and Character Set File Scannerは、言語ごとに複数の文字セットをサポートしています。
言語のバイナリ値が、サブセット/スーパーセット関係を持つ複数のエンコーディングと一致する場合は、サブセットの文字セットが戻されます。たとえば、言語がドイツ語ですべての文字が7ビットの場合は、WE8MSWIN1252、WE8ISO8859P15またはWE8ISO8859P1のかわりにUS7ASCIIが戻されます。
文字セットがUTF-8であると判別されると、テキスト内で4バイト文字(補助文字)が検出されないかぎり、デフォルトでOracleの文字セットUTF8が戻されます。4バイト文字が検出されると、文字セットはAL32UTF8としてレポートされます。
関連項目:
サポートされている言語と文字セットのリストは、「言語および文字セット検出のサポート」を参照してください
11.4.5 LCSSCANエラー・メッセージ
- LCD-00001 An unknown error occured.
-
原因: 内部構造へのアクセス中にエラーが発生しました。
- LCD-00002 NLS data could not be loaded.
-
原因:
$ORACLE_HOME/nls/data
へのアクセス中にエラーが発生しました。 - LCD-00003 An error occurred while reading the profile file.
-
原因:
$ORACLE_HOME/nls/data
へのアクセス中にエラーが発生しました。 - LCD-00004 The beginning or ending offset has been set incorrectly.
-
原因: 開始オフセットと終了オフセットは、1以上の整数である必要があります。
- LCD-00005 The ending offset has been set incorrectly.
-
原因: 終了オフセットは開始オフセットよりも大きい値に設定する必要があります。
- LCD-00006 An error occurred when opening the input file.
-
原因: ファイルが見つからないか、オープンできません。
- LCD-00007 The beginning offset has been set incorrectly.
-
原因: 開始オフセットは、ファイルのバイト数よりも小さい値に設定する必要があります。
- LCD-00008 No result was returned.
-
原因: 入力されたテキストが短いため、結果を生成できません。