web-dev-qa-db-ja.com

MySQLに大きなファイル(〜1GB)を保存する

InnoDBを使用してMySQLに大きなファイルを格納するソリューションを検討しています。ファイルのサイズは250MB-1GBの範囲です(将来、最大50GBに増える可能性があります)。これが計画です。

  1. FILES(id、name)およびFILE_PARTS(id、file_id、sequence int、data LONGBLOB)のような2つのテーブルを作成します。
  2. テーブルFILESの各ファイルへの参照と、FILE_PARTSの大きなファイルの1GBチャンクを追加します。これにより、理論的には任意のサイズのファイルを保存できます。
  3. これらのファイルが必要なときはいつでも、パーツを取得してディスク上で結合し、元のファイルを取得できます。
  4. 古いデータを削除して、FILE_PARTSのデータ量を制限することもできます。 100GB〜200GB程度に制限できるはずです。

私たちが直面する可能性がある制限の種類と、これを機能させるのに役立つ戦略について理解したいと思います。さらにいくつかのことを行う必要がありますか?ここで何か不足していますか?データベースの残りの部分が独自のファイルにある間、FILE_PARTSテーブルを独自のファイルに保持する方法はありますか?データベースのバックアップはどのように反応しますか?


注:リレーショナルデータベースにファイルを保存することは一般に推奨されないことはわかっていますが、私たちの組織では、私たちが生活するためにいくつかの制約があります。それが絶対に機能しない理由に関する理由を知っている場合(5倍の非効率は私たちには問題ありません)、ここに私の人々を説得できるように、ぜひ私に知らせてください。

2
Amit

(OK、4GBを超えるファイルはテーブルに格納する必要があると想定しています...)

4GBを超えるには、LONGBLOBの制限があるため、何らかの形式のチャンクが必要です。

あなたをつまずく多くの設定があります。設定は、MySQLサーバー、mysqldump、MySQLレプリケーション、Apache、ネットワーク、さまざまなタイムアウトなどで発生します。1MBのチャンクはほとんどの状況で安全です。 1 GBは、回避しにくい制限に達する可能性が非常に高くなります。たとえば、max_allowed_packetには1 GBのハード制限がありますが、実際の制限ははるかに低くなっています。とにかく、1GBの200チャンクと1MBの200Kチャンクの間にコードや速度の違いはあまりありません。実際、小さなチャンクmightの方が高速です。

10年前に同様のものを実装したとき、50KBのBLOBが適切なチャンクサイズであると判断し、各チャンクをclientコードで個別に圧縮しました。私のセットアップにはレプリケーションが含まれていたため、レプリケーションストリームを占有しないように、各チャンクを個別に挿入するように注意しました。

50GBをシャベルで削るには、かなりの時間がかかります。 Do not単一のInnoDBトランザクションですべてを実行します。代わりに、チャンクを楽観的に別のトランザクションに格納し、マスターレコードの最終的なストアの前にクラッシュした場合にのみ、ゴミを心配します。

ほとんどの画像フォーマットはすでに圧縮されているため、再圧縮するのは無駄です。

はい、2つのテーブルはほぼ「正しい」ものです。いいえ、5倍の問題は発生しません。ただし、単にファイルとして保存する場合に比べて2倍の劣化が生じる可能性があります。

2
Rick James