LONGBLOB
アラビア語のテキスト データを含むフィールドで検索を実行したいと考えています。たとえば、U はどのように検索しますか?テーブル フィールドには次のような値があります
3313537353B2623313630363B2623313631303B202623313630343B2623313537353B2623313630363B202623313539303B2623313538313B2623313537353B2623313631303B2623313537353B2623313630373B2623313630353B2026
。ただし、アラビア語のテキスト値を取得して Web ページに表示すると、適切なアラビア語の文字が表示されます。フィールドのデータ型を から に変更すると、
LONGBLOB
保存LONGTEXT
したアラビア語のコンテンツ テキストに影響しますか? そのテーブルにはほぼ 1500 のレコードがあります。
2 に答える
文字とそのエンコーディングの違いを理解することが重要です。
ن
たとえば、文字は、そのエンコーディングに応じて非常に異なるバイトで格納されます。たとえば0xcc
、IBM1097 コードページでエンコードされた場合は 1 バイトで表されますが、0xfefffee5
UTF-16 でエンコードされた場合は 4 バイト シーケンスで表されます。さらに悪いことに、同じエンコーディング内で同じ文字が複数の方法で表現される場合があります。MySQL は、使用されたエンコーディングを認識しない限り、必要な種類のテキスト比較を実行できません (同じバイト シーケンスを検索するためにバイナリ比較を実行できますが、これは目的の照合を適用しません。たとえば、大文字と小文字を区別しない、または同じ文字を表す異なるバイト シーケンスなど)。
したがって、検索を実行するときに MySQL にエンコーディング情報を提供するか、MySQL が最初にデータを受信した瞬間からそれを追跡するようにする必要があります (つまり、バイナリ型ではなく文字列型の列にデータを格納することによって)。 )。
テキストデータを文字列型の列に格納する方 がはるかに一般的です (実際、私は強くお勧めします)。
LONGTEXT
1 つの可能性ですが、必要に応じてやり過ぎかもしれません。最大 4GiB のデータを保存できます。おそらくTEXT
、またはVARCHAR
(両方とも最大64KiBを保持できる)またはMEDIUMTEXT
(最大16MiB)がより適切でしょうか?文字データであると理解されると、MySQL は文字列比較関数または正規表現を使用してテキストを簡単に検索できます。例えば:
SELECT * FROM mytable WHERE textcolumn LIKE '%هذه «الأولويات الدواوينية» ف%';
これにより、フィールド内の任意の場所に指定された文字列が (照合に従って) 含ま
mytable
れるレコードが検索されます。textcolumn
最初に、既存のデータがどのエンコーディングで列に格納されているかを理解する必要があり
LONGBLOB
ます (これは、元のクライアントがデータを挿入/更新したときに使用したエンコーディングです)。その後、問題なく文字列型の列に変換できますが、レコード間で異なる場合は、ケースバイケースで各レコードの変換を管理する必要があることに注意してください (ただし、同じ問題に直面することにもなります)。とにかく現在のデータを取得するとき)。たとえば、データが UTF-8 を使用してエンコードされている場合、列を
TEXT
次のように変換できます。ALTER TABLE mytable MODIFY textcolumn TEXT CHARACTER SET utf8;
文字列データの送信/取得時に必要な変換が確実に行われるように、接続文字セットがクライアントに対して正しく構成されていることを確認する必要があることに注意してください。
あなたの2つのオプションに対する可能な解決策として私が見ているものは次のとおりです。
longblob の保持:テキストの内容全体を検索したい場合は、いつでも longblob に対して MD5 サム (またはその他のハッシュ アルゴリズム...あなたに適したもの) を実行し、それを検索できます。この MD5 列にインデックスを付けて、倍長整数などにすると超高速検索ができるようにすることもできます。
このアプローチの問題は、レコードを見つけるためにテキストの内容全体を知らなければならないことです。考えられる解決策は、テーブル内のレコードにリンクされたサブジェクト トークンを、別のテーブルに格納して検索できる longblob で提供することです。その後、トークンに一致する longblob テーブルから行を返すことができます。たとえば、映画、劇場、評論家、俳優について説明するテキストがある場合、「映画」、「劇場」、「評論家」、「俳優」のトークンを作成し、それらをトークン テーブルに保存します。記事を含むロングブロブ テーブル エントリへの外部キー、そしてユーザーが「映画」や「批評家」などを検索すると、それらの特定のトークンに一致したため、ロングブロブ テーブルのその行が返されます。
ロングテキストへの変更: ロングテキストを使用するように変換すると、内部を検索できるようになるため、検索機能が向上します (ただし遅くなります)。私だったら、メイン フィールドのタイプとして longtext を使用して新しいテーブルを作成し、BLOB からアラビア語データを読み取り、それを新しいテーブルにテキストとして書き込むスクリプトを記述します。フォーマットなどが正しいことを確認すれば、データが破損することはありません。単純に変換するだけで破損するかどうかはわかりません...長いブロブでテーブルを作成し、アラビア語のテキストを入力してから、列を長いテキストに変換し、何が起こるか見てください。