Base64でエンコードされたデータをデータベースに保存しないでください...
Base64は、任意のバイナリデータが印刷可能なテキスト文字のみを使用して表されるコーディングです。このようなバイナリデータを、印刷可能なテキスト(SMTP /電子メールなど)のみを処理できるプロトコルまたはメディアを介して転送する必要がある状況向けに設計されました。データサイズが(33%)増加し、エンコード/デコードの計算コストが増えるため、どうしても必要な場合を除いて、これは避ける必要があります。
対照的に、列の要点は、BLOB
不透明なバイナリ文字列を格納することです。BLOB
したがって、最初にBase64でエンコードせずに、列に直接保存してください。(とはいえ、MySQLが保存されている特定のデータに適したタイプである場合は、代わりにそれを使用することをお勧めします。たとえば、JavaScriptソースなどのテキストファイルは、TEXT
MySQLがテキスト固有のメタデータをネイティブに追跡する列に保存することでメリットが得られます。 —これについては以下で詳しく説明します)。
SQLデータベースが任意のバイナリデータを処理するためにBase64のような印刷可能なテキストエンコーディングを必要とするという(誤った)考えは、多くの情報不足のチュートリアルによって永続化されています。このアイデアは、SQLは他のコンテキストでは印刷可能なテキストのみで構成されているため、バイナリデータにも必ず必要であるという誤った考えに基づいているようです(少なくともデータ転送では、データストレージではない場合)。これは単純に真実ではありません。SQLは、プレーンな文字列リテラルを含むさまざまな方法でバイナリデータを伝達できます(他の文字列と同様に適切に引用符で囲まれ、エスケープされている場合)。もちろん、(任意のタイプの)データをデータベースに渡すための推奨される方法は、パラメーター化されたクエリを使用することです。パラメーターのデータ型は、他のものと同じように簡単に生のバイナリ文字列にすることができます。
...パフォーマンス上の理由でキャッシュされていない限り...
Base64でエンコードされたデータを保存することでメリットが得られる唯一の状況は、データベースから取得した直後に、そのようなエンコードを必要とするプロトコルを介してデータが送信される場合です。この場合、Base64でエンコードされたデータを保存します。表現は、フェッチのたびに生データに対してエンコード操作を実行する必要がなくなります。
ただし、この意味で、Base64でエンコードされたストレージは、パフォーマンス上の理由で非正規化されたデータを格納するのと同じように、単にキャッシュとして機能していることに注意してください。
...その場合はそうではありTEXT
ませんBLOB
上で示唆したように、と列の唯一の違いはTEXT
、列の場合、MySQLがテキスト固有のメタデータ(文字エンコードや照合など)を追加で追跡することです。この追加のメタデータにより、MySQLはストレージと接続文字セット(適切な場合)の間で値を変換し、高度な文字列の比較/並べ替え操作を実行できます。BLOB
TEXT
一般的に言えば、異なる文字セットで動作する2つのクライアントが同じバイトを表示する必要がある場合は、BLOB
列が必要です。同じ文字TEXT
が表示される場合は、列が必要です。
Base64では、これら2つのクライアントは、データが同じバイトにデコードされることを最終的に検出する必要があります。ただし、保存/エンコードされたデータが同じ文字であることがわかります。たとえば、'Hello world!'
(である'SGVsbG8gd29ybGQh'
)のBase64エンコーディングを挿入したいとします。挿入アプリケーションがUTF-8文字セットで動作している場合は、バイトシーケンス0x53475673624738676432397962475168
をデータベースに送信します。
そのバイトシーケンスがBLOB
列に格納され、後でUTF-16 *で動作しているアプリケーションによって取得された場合、同じバイトが返されます。これ'升噳扇㡧搲㥹扇全'
は、目的のBase64エンコード値ではなくを表します。一方
そのバイトシーケンスがTEXT
列に格納され、後でUTF-16で動作しているアプリケーションによって取得された場合、MySQLはオンザフライでトランスコードしてバイトシーケンスを返します。これは、必要に応じ0x0053004700560073006200470038006700640032003900790062004700510068
て元のBase64エンコード値'SGVsbG8gd29ybGQh'
を表します。
もちろん、それでもBLOB
列を使用して文字エンコードを他の方法で追跡することはできますが、それでも不必要に車輪の再発明が行われ、メンテナンスが複雑になり、意図しないエラーが発生するリスクがあります。
BLOB
*実際、MySQLはASCIIとバイト互換性のないクライアント文字セットの使用をサポートしていません(したがって、Base64エンコーディングはそれらの任意の組み合わせで常に一貫しています)が、この例は、列タイプとTEXT
列タイプの違いを説明するのに役立ちます。実際にはエラーなしで機能するにもかかわらず(少なくともMySQLが非ASCII互換のクライアント文字セットのサポートを追加するまで)TEXT
、この目的に対して技術的に正しい理由を説明します。BLOB