5

mysqlMyISAMテーブルには、列タイプがmediumblobあり、キャプチャされた画像をblobデータとして保存しています。面白くて問題のある画像がいくつかありました。一部の画像はgradually losingデータです。

Field          type  
--------------------------
image         mediumblob

my.ini設定された最大許容パケットサイズmax_allowed_packet = 8M

image1 image2 image3

これが問題です

アプリケーションがサーバーからデータをフェッチするC#と、この種の画像は毎回ランダムなサイズのデータ​​を失います。10-12このような悪い画像が画像100000+データに含まれています。

この種の行動の理由は何でしょうか?誰もがこの問題を修正/回避する方法についてのアイデア/解決策を持っています。

更新1:
PictureBoxからバイトを読み取る

MemoryStream ms = new MemoryStream();
byte[] ret = null;

try
{
     picturebox.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
     byte[] Data = new byte[ms.Length];
     ms.Read(Data, 0, (int)ms.Length);
     ret = byteData;
     ms.Close();
 }         
 

バイト配列を中程度のBLOBデータとしてデータベースに保存します。データベースからデータを取得するとき、リーダーデータをキャストしています。

byte[] Data = (byte[])reader["Image"];
4

5 に答える 5

6

まず第一に、Sarke が述べたように、ファイルのコンテンツを DB に保存することは最善のアイデアではありません (ファイルのメタデータはまったく別の話です。

なんで?

  1. パフォーマンス: ほとんどの場合、OS ファイル キャッシュは、DBMS に組み込まれているものよりもパフォーマンスが優れています。
  2. ディザスタ リカバリ: 障害時にすべてまたはほとんどのファイルが失われる可能性は、ファイル システムの場合よりもはるかに高く、リカバリははるかに困難です。
  3. スケーリング: 単一サーバーの容量を超えた場合、アプリケーション レベルのシャーディングを追加することは簡単であり、パフォーマンスが低下することはありません。マルチサーバー DB のセットアップはより「面倒」です
  4. 複数のソリューションを利用可能/移行の容易さ: 大規模なファイル コレクション ストレージ用のハードウェアおよびソフトウェア ソリューションが多数あり、それらの間の移行は DBMS 間で移行するよりもはるかに簡単です。

単純なフォルダー構造に保存されている 200 万枚近くの画像を保存します。/xx/yy/filenameここで、ファイル名 = ファイルの md5 (+ ハッシュ衝突が発生した場合のオプションの番号)、xx = md5 の最初の 2 文字、yy = md5 の 3 番目と 4 番目の文字. それはうまく機能し、FS関連のスローダウンはしばらくの間発生しないはずです(少なくとも2桁)。

質問に戻ると、3 つのオプションがあります

  1. ファイルは DB に正しく保存されません。写真をアップロードしているアプリの問題か、画像が大きすぎる可能性があります。max_allowed_packet画像サイズを最大 8 MB に制限し、最大mediub_blob16 MB を保存できます。これを除外するにはmax_allowed_packet、32 MB に増やしてテストします。どの時点でもこのサイズを超える画像がないことを確認し、写真をアップロードするときにアプリが正しく機能することを確認する必要があります. アップロードされて (DB から!) 正常に表示された画像が見つかり、後で表示されなかった場合、これは原因ではありません。
  2. 更新中にファイルが破損します。何らかの方法で写真が更新された場合、元のファイルが正常であっても、更新されたファイルが更新されていない可能性があります。たとえば、ポイント 1 のサイズ制限を超えている可能性があります。
  3. (最も可能性が低いもの)ファイルが損傷することなく保存および更新されている場合、保存中に損傷を受けています->これに関するMySQLのバグは報告されていません(これは見過ごされません)私はサーバーハードウェアを調べます.
于 2012-06-15T17:30:03.160 に答える
4

原因は MyISAM ストレージ タイプです。

InnoDB ストレージを使用して 100 万枚の画像を保存し、ストレス テストを実施したところ、適切な結果が得られました。InnoDB は酸に準拠しているため、ファイルが正しく取得されたか、まったく取得されませんでした (0.01% 未満)。

MyISAM に移行したとき、お客様のケースと同様に、損失のあるデータで失敗率が 20% に増加しました。その理由は、MyISAM がテーブル ロックを使用しているため、書き込みの進行中にテーブル全体がロックされ、タイムアウトが発生した場合、何かが上書きされてデータが失われるためです。

InnoDB のパフォーマンスは良好ですが、削除されたファイル スペースを再利用することはありません。したがって、InnoDB は際限なく成長し続けます。MS SQL Express には 10 GB の制限があるため、4 ~ 8 GB のページを作成し、そこに BLOB を保存します。また、同じ構成でネットワーク全体の 3 台のサーバーにファイルを複製するための独自のカスタム レプリケーションがあります。

ファイルをディスクに保存することは多くの理由で良くありません。ファイル システムは高パフォーマンス向けに設計されており、何百万ものファイルを保存できると誰もが言い続けていますが、これは正しくありません。10 万を超えるファイルがあると、ドライブのパフォーマンスが向上しません。1 つの大きなファイルと 1000 個の小さなファイルでうまく機能します。現在、1,000 万個のファイルを保存しています。db はクエリに対して最適化を行い、適切なキャッシュを行うため、db に保存する方が理にかなっています。詳細については、http://akashkava.com/blog/127/huge-file-storage-in-database-instead-of-file-system/を参照してください。

これが、MongoDb、Hadoop、Azure Blob Store、Haystack、および Amazon S3 が発明された正確な理由です。

于 2012-06-22T07:35:48.487 に答える
2

このデータを変更するのは、アプリケーションなのか、外部プロセス(バックアップ/復元?)なのかを最初に把握する必要があると思います。実際、ファイルが変更されないままであると想定される場合、アプリケーションがこの画像を更新する必要がある(つまり、同じデータでフィールドを更新する)必要がある理由はほとんどわかりません。

アプリケーションのどの部分がこのフィールドを更新するかを見つけたら、コードを投稿して、変換やエスケープなどが行われていないかどうかを確認することをお勧めします。

私が想定しているように、そのような更新が発生しない場合はBEFORE UPDATE、テーブルにトリガーを設定すると、問題がいつ発生するかを正確に知ることができ、考えられるパターンを特定するのに役立つ場合があります。OLDとの値を比較し、NEW関連する利用可能なデータをできるだけ多くログテーブルに記録します。大きなBLOBを比較すると、パフォーマンスが低下する可能性があることに注意してください。パフォーマンスを注意深く監視してください。

于 2012-06-16T02:49:15.750 に答える
1

私の会社は、データベースの外部に画像を保存することを選択しています。使用しているような BLOB は、破損やパフォーマンスの問題が発生しやすいことに気付きました。MSSQL、Sybase、Faircom でも同じ問題が発生しました。

アプリケーションが画像にアクセスする必要があるときはいつでも、その画像を見つけることができるネットワーク (または Web ベース) ストレージにアクセスする必要があります。次に、データには画像へのパスのみが保存されます。

イメージはファイル システムのどこかにあるフラット ファイルであるため、レコードを更新する必要がある場合 (つまり、イメージを説明するためにメモを追加する場合)、それ自体のイメージは blob に再コンパイルされず、次の可能性はありません。破損しています。

于 2012-06-19T13:00:09.350 に答える
0

データベースからデータを取得するためにどの API を使用していますか? データをフェッチするコードを入手してください。

通常、BLOB は何らかの「ストリーミング」を使用してデータベースから読み取られるため、ADO.NET を使用している場合は、ADO.NET よりも堅牢なものに切り替える必要があるかもしれません。

このページは役に立つかもしれません: http://dev.mysql.com/doc/refman/5.5/en/connector-net-programming-blob.html

于 2012-06-16T12:36:44.883 に答える