データベースに画像を保存するのはありでしょうか?
解決済
回答 12
投稿 2017/06/21 14:46
- 評価
- クリップ 9
- VIEW 2,647
商品登録データベースを作成したいと思っております。
商品画像データをデーターベースに登録したいと思い、
初心者ながらgoogleで色々調べてみたところ、
データ型を「mediumblob」にすると画像を保存できるという記事を見かけましたが、
基本的にデーターベースには画像を保存しないほうがいいというご意見もありました。
普通は画像のパスをデーターベースに保存する、という意見でした。
基本的にはどちらが良いのでしょうか?
(データーベースに負荷を与えない画像保存?)
皆様のご意見をお聞かせください。
宜しくお願い致します。
-
気になる質問をクリップする
クリップした質問に回答があった場合に通知・メールを受け取ることができます。
クリップした質問はマイページの「クリップ」タブからいつでも見ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+18
オススメの結論から言うと 保存しない に一票かと思います。
理由
1レコードのデータ量が多くなり、クエリに時間がかかる
画像ファイルは通常のカラムよりデータ量が多いため、SELECT、UPDATE、INSERT共に処理時間が多くかかります。
MySQLは最終的にテーブル単位の実ファイルにデータを格納します。
もし毎回画像データもSELECTした場合、大きなテーブル(ファイル)の中から該当レコードを読み込みます。
画像をUPDATEする場合、INSERTする場合も、通常のカラムではせいぜいvarchar(255)などに比べ、例えば4kb(4096byte)など、小さい画像でも、DBにとっては大きなデータになります。
故に 処理時間 は考慮した方が良いかな、と思います。
DBのストレージ容量を圧迫する
画像を含むレコード数がどれくらいかわからないのですが、商品であったとして、継続的にデータが増えていくものとします。
この場合、データベースのサーバーの容量が 通常のレコードの容量の想定を超えて 増加することになります。
WebもDBも1つのサーバーで動く小規模システムならば許容できるかもしれないのですが、
- サムネイルも保存したい
などとなれば、さらに容量を圧迫する場面もあるかもしれません。
また、静的ファイルのデータ量と、テーブルのカラムに保存したデータ量では、若干ですがカラム保存の方が容量が多くなります。
WebとDBを分割しようと思った時に弊害がある
- 将来的にWebとDBを分ける
- やっぱり画像やJavaScript、CSSなど静的ファイルは別の場所に置きたい
などが発生した場合、容易に分けられなくなる、と言う弊害もあるかな、と思います。
テーブルに格納されている画像データを片っ端から読み込んでは、画像の実ファイルに保存する。
そう言った処理を 存在するレコード数 だけ処理しなければならない場面が将来的に想定できるならば、画像は最初から静的ファイルで保持した方が良いかな、と思います。
ネットワークを圧迫する
また、ネットワークを流れるデータ量も多くなります。
WebサーバーとDBサーバーを分けている(もしくは将来的に分ける可能性がある)場合、Web←→DB間のネットワークを圧迫します。
Web側に多くリクエストがきた場合、DBで捌ききれずにWeb、DBいずれかがタイムアウトを起こし、ユーザーの画面が真っ白、と言うことも起こりかねません。
DBからネットワークに流すデータ量は少なければ少ない方が良いと思います。
メンテナンス性が低下する
画像は一度保存したら絶対に更新しない、と言うわけではないと思いました。
その場合、通常ならばサーバーに画像をアップロードすればいいはずが、必ずプログラムなどからSQLを実行しなければならない、と言う 何段階も余計な手順を踏む 必要性が出てくることが想定されます。
また、SQL実行するので、余計なバグで他のデータに影響を与える可能性もあります。
静的ファイルは ピンポイントにサクッと更新できる 状態にしておいた方がいいかな、と思いました。
キャッシュしにくくなる
ユーザーのブラウザ上での読み込み速度向上などの為に、画像を含む静的ファイルをキャッシュとして配信したい場面が出てくることがあります。
その場合、静的ファイルであれば簡単ですが、DBに保存されている場合は違う手順を踏む必要があるかと思います。
踏む手順が多くなると、それだけ運用効率も下がり、保守性が低下したり、いいことがなかったりします。
今後の運用・保守も視野に入れ、設計することをオススメしたいです。
利点
僕自身、これと言った利点が思い浮かびませんでした。
強いていえば
- SQLだけで画像も含めた商品データが取れる
くらいかと思いましたが、それならば 画像は静的ファイル にして、 相対パスをテーブルのカラムに保持 の方が現実的かな、と思いました。
ご参考になれば幸いです。
間違いなどあれば指摘いただければ助かります。
投稿 2017/06/21 15:23
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+12
私自身の意見ではないのですが、Oracle さんの資料で面白いものがありました。
データベースに画像を格納するメリット
こちらの資料を読むと、パフォーマンスやデータサイズで DB 保存を諦めるのは、判断基準としてあまり適切ではなく、優位点(管理やセキュリティ、バックアップ/リカバリ等)を考慮すべきですよ。といった内容になっています。
MySQL ではなく、oracle 資料なので微妙ですが、参考まで。
投稿 2017/06/21 15:46
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+4
システムの保守などをやる場合、DBのデータを手入力で修正したりするケースが出てきます。
そういう場合、DBに格納されているデータは「Selectの結果が視認可能」で「Update/InsertがシンプルなSQL文で実行可能」な方が作業しやすいです。
という訳で個人的には「データベースに画像を保存しない方がいい」に一票。
投稿 2017/06/21 14:53
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+3
予算的、システム的、政治的に可能であれば、いちばんのおすすめは、保管先をDBでもローカルのディスクでもなくオブジェクトストレージ(AWS S3など)にすることです。
保存するときも容量不足などを考えずに済みますし、パブリックで良ければそのままHTTP配信もできてしまいます。という感じに、ファイル管理からほぼ解放されるので、かなり楽です。
投稿 2017/06/21 19:46
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+2
ストレージの容量によるのではないでしょうか?
例えば Web サイトを公開するために自分が使っているレンタルサーバーですと、3 GB の容量の内 DB サーバに使えるのは 300MB のみですが、そのような場合は画像本体は Web サイトのどこかのフォルダ、DB サーバーに保存するのはその画像へのパスにせざるを得ません。
投稿 2017/06/21 15:01
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+2
私はどちらも一長一短だとはおもいますが、質問者さんの状況であれば、「データーベースには画像を保存しない」ほうをおすすめですね。
理由はリファレンスの多さの違いです。何か追加機能を実装しようとしたときに、RDBに保存する設計より、ファイルサーバーに格納するほうが圧倒的に情報は見つかりやすいと思います。ま、ケースバイケースですが。
RDBに保存するすたいるは後々トライするくらいでいいかと思います。
投稿 2017/06/21 15:05
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+2
管理の面から考えると格納しない
方をおすすめします。
DBに保存するのは画像があるパスに留めた方が良いかと思います。
投稿 2017/06/21 15:40
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+2
基本的にデータベースに画像は保存しない方がいいです
SQLで画像データいじるなんてしません
逆にデータベース云々抜きにして画像をどうこうしたい場合はあります
画像の中身に応じてサーバー側の処理を分岐なんてそうそうしないはずです
SQL側で画像が不要な場合や不要な行は取り出さないように
っていうのを徹底しないとメモリの負荷が半端なくなります
それでなくてもサーバー側の処理が画像のデータを
全部読み込むまでストップしちゃいます
データベースに画像を入れる方が色々スムーズと言えるのは
プログラムで動的にQRコードやアイコン程度のサイズの画像を
生成する場合ぐらいと思います
投稿 2017/06/21 15:48
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+2
たとえば一切のファイルI/Oを認めたくないという運用ポリシーがあるなら
選択肢はDB上に保存しておくしかないかもしれません。
そうではないならDBからデータを抽出するよりファイルI/Oの方が効率がよいので
ファイル本体をDBにおくメリットがほとんど感じられません。
バイナリデータの中になにか特殊なデータを含むものを検索することは
運用上考えられませんし、もしそれをやるとなるとDB自体のパフォーマンスは
あまり期待できません。
結果として画像本体はデバイス上にファイルとしておき、必要に応じて
その詳細情報はDBに転記しておくのがまっとうな使い方になると思います
サイズ、ファイル名、長さ、高さ、content-type、登録日、管理者などなど
投稿 2017/06/21 15:55
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
+1
設計次第ですが、「直接DBに保存しない」派です。
私がよくやる設計ではこんな感じ。
- アップロードした画像の置き場は決めておく(1ディレクトリに集中しすぎないように分散)
- アップロード時に画像をリネームして命名規則(例えばレコードのIDやカテゴリ名など)に則る
こうすると、拡張子文字列だけを保存しておくというやり方になります。
また、拡張子まで限定した場合はそれすら不要にできたりします。
他の方が仰るように容量の問題や速度の問題、処理上の問題もあると思いますので、
仕様や設計によって決めるのが良いでしょう。
商品情報とのことなので、一般的に閲覧可能なものでどんどん増えていき、また削除や更新もされるでしょうから、
DB保存はおすすめしませんね。
投稿 2017/06/21 17:09
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
0
自分はデータベースなど詳しく無いですが先日MSのSQL Serverの新機能でデータベースからディープラーニング出来るようになりました!とか言っててそれなんの意味があるのと思ったんですが上にも上がってるようにデータベースサーバーのセキュアな仕組みを画像などにも適用して格納し、それをそのままディープラーニングの推論だか学習だか忘れましたがキックできるということらしくなるほどと思いました。
関係ないですが自分はバイナリの一定のサイズのものはAzureのBlobに突っ込んで安くしたりしてますね。用途によってはどぞー。
投稿 2017/06/27 09:04
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
0
もう解決してしまってますが・・
画像の更新・参照頻度が低ければDBに入れるのもアリだとは思います。
が、画像データを扱うとデータ量や転送量の問題があるので、外部に置くのが良いかなと思います。
自分なら、画像自体はS3に保存してしまって、DBにはそのS3のパスを保存しておく。
参照が多い場合はCDN経由で画像を表示出来るようにしておく。
等の選択をするかなぁと思います。
投稿 2017/06/27 10:25
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
以下のような回答は評価を下げられます
- 間違っている回答
- 質問の回答になっていない投稿
- 不快な投稿
評価を下げる際はその理由をコメントに書き込んでください。
15分調べてもわからないことは、teratailで質問しよう!
91.86%
2017/06/21 15:57
2017/06/21 16:05
2017/06/21 16:10
mysqlにアクセスできればどこからでもデータが取り出せるメリットはあります
逆に無駄にでかいバイナリデータがリプリケーションの邪魔になるんですけどね
もちろんファイルとして置いておいても同じことはできるので
RDBの特性とまではいいきれません
2017/06/21 16:14
2017/06/21 16:24
スレーブが検索サーバーになると思われますので、規模が大きくなると遅延が怖いですね。。。
一般的にはrsync(扱い間違うとこれも怖い)だったり、S3にnginx立てて静的サーバー、それ以上になると各種キャッシュ機構やCDN、とかになるんだと思いました。
当たり前ではありますが、サービスの特性を考えてしっかり運用設計しましょう、と言うところに落ち着くんだと思います。
> セキュリティ
差し支えなければ、画像をセキュアに取り扱う場面を教えて欲しいなと思いました。
実際の顔画像などの個人情報、それにひもづく機微情報ならば想定できるのですが、それ以外だと「業務システムなどに特化した機密情報」くらいしか思いつきませんでした。。。
個人的な考えですと、「構築が楽」を「のちの保守や運用、トラブル耐性や拡張性」とトレードオフした際に、どっちがいいか、と言う話になると思っています。
2017/06/21 16:34
私の経験だと「電子カルテ」ですね。
2017/06/21 16:38
なるほど、紙や直筆の添付資料が多く、全てを関連づけて、かつセキュアにしなければならない、であっていますでしょうか?
想定できていなかった事例でしたが、一瞬でも医療関連のシステム(レセプト系)に関わった者として、非常に参考になりました。ありがとうございます!
2017/06/23 12:44
貴重なご意見、誠にありがとうございます!
とても細かく記載していただきありがとうございます。
参考にさせていただきます。
またコメントをしてくださっている方もありがとうございます。
2017/06/23 15:57 編集
こちらこそありがとうございます!
あれからエンジニアの友人知人と議論した結果、僕の中では以下のこと「も」言えるという結論に至りました。
(僕の回答と重複する部分もあります)
# デメリット
- RDBに画像を持たせることは、パフォーマンスをかなり犠牲にする
- 詳細は上述していますので割愛しますが、書き込み読み込み速度の遅さは、実務に耐えられないレベルで低下した事例がいくつか聞けました
- 増え続ける画像をRDBに入れるのはパフォーマンスをはじめデメリットが多いので避けた方がいい
# メリット
- RDBトランザクションを利用することで、エラーの時に一度でロールバックできる(ファントムファイルが防げる)
- 暗号化、よりセキュアにファイルを取り扱いたい場合(shoko1さんおっしゃるように電子カルテへの添付画像など)はRDBで取り扱う方が設計、実装、運用が楽
- 特殊な画像の場合で、数が少ないことが想定される場合は有効
- 画像がデータベースに集約されるので、バックアップとリストアは容易になる可能性が高い
- ただし単一障害点(SPOF)になるので注意が必要。DBが壊れると画像全てを失う
# 代替案
- AWSのS3が使えるなら、そちらを画像サーバーとしてしまうのがベスト
- Webサーバーが複数台になった場合は、画像ファイルの同期方法を考える必要がある
# その他注意点
- アプリケーションで画像を取り扱う際は、ファントムファイルにならないよう注意する
結局のところ「パフォーマンス・機能開発工数・運用保守工数とのトレードオフ」ということが言えると思いますので、サーバーの今後の構成を考えて、設計すると後々幸せになれるのではないかな、と思います。
パフォーマンスを犠牲にしてでも、
- 早く実装したい
- 特殊な要件がある
- トランザクションで一括処理したい
- 監査(閲覧、変更履歴が欲しい)した場合
- 画像をバージョン管理したい
などの要件があれば、RDBに保存することも考慮の1つに入るかな、と思っています。
特に下3つはアプリでの実装に工数がかかると思われますので。
また、蛇足ではありますが、「SQLアンチパターン」という書籍を読んでみることをオススメします。
「こういう使い方はこういう弊害があるよ」というバイブルです。
ではでは、ありがとうございました。
2017/06/23 16:11
2017/06/23 16:12
こちらこそ、コメントくださったからこそ「深掘りしてみよう」という気持ちになれました。
ありがとうございました!