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