sql >> データベース >  >> RDS >> Mysql

base64でエンコードされたデータをBLOBまたはTEXTデータ型として保存する

    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を使用することはできます 列を作成し、他の方法で文字エンコードを追跡しますが、それは不必要に車輪の再発明を行い、メンテナンスの複雑さが増し、意図しないエラーが発生するリスクがあります。




    1. PHP配列のコンテンツをMySQLデータベースに保存する

    2. 2つの緯度/経度ポイント間の距離を見つける最速の方法

    3. intをvarcharにキャストします

    4. なぜJOIN句とWHERE条件を使用するのですか?