質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

13回答

129539閲覧

データベースに画像を保存するのはありでしょうか?

beginner_39

総合スコア77

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

19グッド

55クリップ

投稿2017/06/21 05:46

19

55

###商品登録データベースを作成したいと思っております。
商品画像データをデーターベースに登録したいと思い、
初心者ながらgoogleで色々調べてみたところ、
データ型を「mediumblob」にすると画像を保存できるという記事を見かけましたが、
基本的にデーターベースには画像を保存しないほうがいいというご意見もありました。
普通は画像のパスをデーターベースに保存する、という意見でした。

基本的にはどちらが良いのでしょうか?
(データーベースに負荷を与えない画像保存?)

皆様のご意見をお聞かせください。

宜しくお願い致します。

kirimaro, kai0310, KIHA, ssmxgo, motikan, musix55, azu, kitajima_rccm, annderber, chazukeo, 他9名👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答13

0

ベストアンサー

オススメの結論から言うと 保存しない に一票かと思います。

理由

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 06:23

mamy1326

総合スコア151

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2017/06/21 06:57

あえて利点をいえば「達成感」ですね
mamy1326

2017/06/21 07:05

なるほど・・・。そもそもRDBに入れるのか?と言うことを考えれば、利点は達成感くらいしかないのかもしれません。
yambejp

2017/06/21 07:10

一応真面目に考えると、リプリケーションの絡みがあるので mysqlにアクセスできればどこからでもデータが取り出せるメリットはあります 逆に無駄にでかいバイナリデータがリプリケーションの邪魔になるんですけどね もちろんファイルとして置いておいても同じことはできるので RDBの特性とまではいいきれません
shoko1

2017/06/21 07:14

セキュリティ(アクセスコントロール)は利点だと思います。サーバに侵入されても見せたくない画像とか…。まあ、ファイルシステムでも対応可能でしょうが、DBのほうが構築が楽だと思います。
mamy1326

2017/06/21 07:24

> レプリケーション スレーブが検索サーバーになると思われますので、規模が大きくなると遅延が怖いですね。。。 一般的にはrsync(扱い間違うとこれも怖い)だったり、S3にnginx立てて静的サーバー、それ以上になると各種キャッシュ機構やCDN、とかになるんだと思いました。 当たり前ではありますが、サービスの特性を考えてしっかり運用設計しましょう、と言うところに落ち着くんだと思います。 > セキュリティ 差し支えなければ、画像をセキュアに取り扱う場面を教えて欲しいなと思いました。 実際の顔画像などの個人情報、それにひもづく機微情報ならば想定できるのですが、それ以外だと「業務システムなどに特化した機密情報」くらいしか思いつきませんでした。。。 個人的な考えですと、「構築が楽」を「のちの保守や運用、トラブル耐性や拡張性」とトレードオフした際に、どっちがいいか、と言う話になると思っています。
shoko1

2017/06/21 07:34

> セキュリティ 私の経験だと「電子カルテ」ですね。
mamy1326

2017/06/21 07:38

> 電子カルテ なるほど、紙や直筆の添付資料が多く、全てを関連づけて、かつセキュアにしなければならない、であっていますでしょうか? 想定できていなかった事例でしたが、一瞬でも医療関連のシステム(レセプト系)に関わった者として、非常に参考になりました。ありがとうございます!
beginner_39

2017/06/23 03:44

mamy1326様 貴重なご意見、誠にありがとうございます! とても細かく記載していただきありがとうございます。 参考にさせていただきます。 またコメントをしてくださっている方もありがとうございます。
mamy1326

2017/06/23 06:57 編集

beginner_39 さま こちらこそありがとうございます! あれからエンジニアの友人知人と議論した結果、僕の中では以下のこと「も」言えるという結論に至りました。 (僕の回答と重複する部分もあります) # デメリット - RDBに画像を持たせることは、パフォーマンスをかなり犠牲にする   - 詳細は上述していますので割愛しますが、書き込み読み込み速度の遅さは、実務に耐えられないレベルで低下した事例がいくつか聞けました   - 増え続ける画像をRDBに入れるのはパフォーマンスをはじめデメリットが多いので避けた方がいい # メリット - RDBトランザクションを利用することで、エラーの時に一度でロールバックできる(ファントムファイルが防げる) - 暗号化、よりセキュアにファイルを取り扱いたい場合(shoko1さんおっしゃるように電子カルテへの添付画像など)はRDBで取り扱う方が設計、実装、運用が楽   - 特殊な画像の場合で、数が少ないことが想定される場合は有効 - 画像がデータベースに集約されるので、バックアップとリストアは容易になる可能性が高い   - ただし単一障害点(SPOF)になるので注意が必要。DBが壊れると画像全てを失う # 代替案 - AWSのS3が使えるなら、そちらを画像サーバーとしてしまうのがベスト - Webサーバーが複数台になった場合は、画像ファイルの同期方法を考える必要がある # その他注意点 - アプリケーションで画像を取り扱う際は、ファントムファイルにならないよう注意する 結局のところ「パフォーマンス・機能開発工数・運用保守工数とのトレードオフ」ということが言えると思いますので、サーバーの今後の構成を考えて、設計すると後々幸せになれるのではないかな、と思います。 パフォーマンスを犠牲にしてでも、 - 早く実装したい - 特殊な要件がある - トランザクションで一括処理したい - 監査(閲覧、変更履歴が欲しい)した場合 - 画像をバージョン管理したい などの要件があれば、RDBに保存することも考慮の1つに入るかな、と思っています。 特に下3つはアプリでの実装に工数がかかると思われますので。 また、蛇足ではありますが、「SQLアンチパターン」という書籍を読んでみることをオススメします。 「こういう使い方はこういう弊害があるよ」というバイブルです。 ではでは、ありがとうございました。
yambejp

2017/06/23 07:11

なかなか普段考えないことですが勉強になりした、thx!
mamy1326

2017/06/23 07:12

yambejpさん こちらこそ、コメントくださったからこそ「深掘りしてみよう」という気持ちになれました。 ありがとうございました!
TakeoSaki

2017/06/27 08:43

> また、静的ファイルのデータ量と、テーブルのカラムに保存したデータ量では、若干ですがカラム保存の方が容量が多くなります。 ファイルサイズが5バイトのような半端なサイズの時、実際にはディスク上の1アロケーションブロックを使用することになり、これは4KBや8KBになったりすると思われますが、DBの場合はそのような細かな無駄が省かれるのではないかと思ったのですがどうでしょうか?
guest

0

私自身の意見ではないのですが、Oracle さんの資料で面白いものがありました。
データベースに画像を格納するメリット

こちらの資料を読むと、パフォーマンスやデータサイズで DB 保存を諦めるのは、判断基準としてあまり適切ではなく、優位点(管理やセキュリティ、バックアップ/リカバリ等)を考慮すべきですよ。といった内容になっています。
MySQL ではなく、oracle 資料なので微妙ですが、参考まで。

投稿2017/06/21 06:46

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/21 08:42

貴重なご意見、誠にありがとうございます! さらに添付資料まで大変感謝申し上げます! Oracleとはいえ、構築システムの観点からはとても貴重な資料をいただきました! 参考にさせていただきます!
guest

0

過去に実装経験があります。
容量が極端に大きくない限りは問題ないです。
(innodbは、テーブルごとに保存ファイルを分割するオプションがあるはずです)

画像はそのままではなくbase64エンコードをかけてから入れます。
バイナリをそのまま入れると、うっかり誤ってSELECTすると
端末表示がおかしくなるなど問題がありますが、その手のミスを防ぎます。

またmd5などでハッシュ値を求め、これも同じレコードに含めておきます。
これにより中身のバイナリデータ自体を見なくても同一ファイルかどうかがわかります。
副次機能として、同一データが連続アップされたケースなども判定が容易です。

メリットとしてはトランザクションが使用できるので一貫性が高くなります。
またバックアップ作業も画像とDBの他のデータを別で管理する手間はなくなります。

Webサーバが複数ある環境では、各サーバでSELECTの結果のバイナリを
当該ハッシュ値とプライマリキーとなるIDをファイル名として一時ファイルとして保存し、
X-Sendfile(Apache)かX-Accel-Redirect(nginx)で処理させます。
画像に変更がない限り保存されるファイル名が同じになるのでbase64デコードは1度ですみます。
またできればApache等のサーバ側のキャッシュが働くようにし、
不要なリクエストが発生しないようにします。

この仕組みでは、ユーザがアップした画像ファイルを全サーバにrsyncなどで転送せずとも良いですし、
最初からハッシュ値の先頭文字などをキーとしてimg-8c.example.comなど
画像サーバを固定化すれば、同じ内容の画像は常に同一サーバを見にくるようにでき、
全サーバに全画像を転送するようなトラフィックとストレージのロスがありません。

投稿2017/06/27 08:03

TakeoSaki

総合スコア97

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/07/04 06:11

TakeoSaki様 アドバイス、誠にありがとうございます。 お恥ずかしい限りですが、データベースを利用した開発が今回が初めてで、 聞きなれない横文字や用語があり、少しハテナマークがついてしまいました。 ですが、逆に一つ一つの言葉理解できるチャンスだと思って参考にさせていただきます。 ありがとうございます。
guest

0

システムの保守などをやる場合、DBのデータを手入力で修正したりするケースが出てきます。
そういう場合、DBに格納されているデータは「Selectの結果が視認可能」で「Update/InsertがシンプルなSQL文で実行可能」な方が作業しやすいです。

という訳で個人的には「データベースに画像を保存しない方がいい」に一票。

投稿2017/06/21 05:53

tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/21 07:28

貴重なご意見、誠にありがとうございます! 大変お恥ずかしいのですが、「Selectの結果が視認可能」というのはどうのようなことでしょうか?
tkturbo

2017/06/21 07:40

たとえばMySQLの場合、コマンドラインツールと呼ばれる機能がありますが、Select文の実行結果は文字列として視認できる形で画面に表示されます。 画像データなどのバイナリデータは画面上に意味のある文字列として表示されません。
guest

0

予算的、システム的、政治的に可能であれば、いちばんのおすすめは、保管先をDBでもローカルのディスクでもなくオブジェクトストレージ(AWS S3など)にすることです。

保存するときも容量不足などを考えずに済みますし、パブリックで良ければそのままHTTP配信もできてしまいます。という感じに、ファイル管理からほぼ解放されるので、かなり楽です。

投稿2017/06/21 10:46

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/23 03:47

貴重なご意見、誠にありがとうございます! 参考にさせていただきます!
guest

0

管理の面から考えると格納しない方をおすすめします。
DBに保存するのは画像があるパスに留めた方が良いかと思います。

投稿2017/06/21 06:40

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/21 07:36

貴重なご意見、誠にありがとうございます! たくさんの回答者様より、格納しないとのアドバイスをいただいております! 構築する上で、とてもいい勉強になって助かっております。 ありがとうございます!
guest

0

自分はデータベースなど詳しく無いですが先日MSのSQL Serverの新機能でデータベースからディープラーニング出来るようになりました!とか言っててそれなんの意味があるのと思ったんですが上にも上がってるようにデータベースサーバーのセキュアな仕組みを画像などにも適用して格納し、それをそのままディープラーニングの推論だか学習だか忘れましたがキックできるということらしくなるほどと思いました。
関係ないですが自分はバイナリの一定のサイズのものはAzureのBlobに突っ込んで安くしたりしてますね。用途によってはどぞー。

投稿2017/06/27 00:04

omanuke

総合スコア109

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/07/04 06:15

omanuke様 アドバイス誠にありがとうございます。 参考にさせていただきます!
guest

0

設計次第ですが、「直接DBに保存しない」派です。

私がよくやる設計ではこんな感じ。

  • アップロードした画像の置き場は決めておく(1ディレクトリに集中しすぎないように分散)
  • アップロード時に画像をリネームして命名規則(例えばレコードのIDやカテゴリ名など)に則る

こうすると、拡張子文字列だけを保存しておくというやり方になります。
また、拡張子まで限定した場合はそれすら不要にできたりします。

他の方が仰るように容量の問題や速度の問題、処理上の問題もあると思いますので、
仕様や設計によって決めるのが良いでしょう。
商品情報とのことなので、一般的に閲覧可能なものでどんどん増えていき、また削除や更新もされるでしょうから、
DB保存はおすすめしませんね。

投稿2017/06/21 08:09

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/23 03:47

貴重なご意見、誠にありがとうございます! matsu1006様の設計方法ではございますが、参考にさせていただきます! 容量・速度、よく注意したいと思います!
guest

0

たとえば一切のファイルI/Oを認めたくないという運用ポリシーがあるなら
選択肢はDB上に保存しておくしかないかもしれません。

そうではないならDBからデータを抽出するよりファイルI/Oの方が効率がよいので
ファイル本体をDBにおくメリットがほとんど感じられません。
バイナリデータの中になにか特殊なデータを含むものを検索することは
運用上考えられませんし、もしそれをやるとなるとDB自体のパフォーマンスは
あまり期待できません。

結果として画像本体はデバイス上にファイルとしておき、必要に応じて
その詳細情報はDBに転記しておくのがまっとうな使い方になると思います
サイズ、ファイル名、長さ、高さ、content-type、登録日、管理者などなど

投稿2017/06/21 06:55

yambejp

総合スコア114814

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/23 03:45

貴重なご意見、誠にありがとうございます! i/oの観点からは考えた事ありませんでした。 今後の運用を考えながら参考にさせていただきたいと思います!
yambejp

2017/06/23 07:05

イメージとして、DBにでかいバイナリを入れるということは 何百何千あるファイルを常に1つのzipファイルにアーカイブしているようなものです。 テーブル上に保存する限り、データを追加するにも削除するにも1つのファイルなので うん百GないしTのファイルの読み込み書き出しが必要になります。 RDBは遅延書き込みをするとはいえ、極端に大きなファイルをもたせると ファイル破損によるリスクも怖いところです。 すくなくとも適当な単位でパーティショニングしないとまずいような気がします
beginner_39

2017/07/04 06:17

yambe.jp様 ご返信、ありがとうございます。 ご回答を見ていると、とても慎重に行わなければいけないなと感じました! ありがとうございます!
guest

0

ストレージの容量によるのではないでしょうか?

例えば Web サイトを公開するために自分が使っているレンタルサーバーですと、3 GB の容量の内 DB サーバに使えるのは 300MB のみですが、そのような場合は画像本体は Web サイトのどこかのフォルダ、DB サーバーに保存するのはその画像へのパスにせざるを得ません。

投稿2017/06/21 06:01

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/21 07:30

貴重なご意見、誠にありがとうございます! 容量もやはり圧迫されてしまうのですね。。 ※容量も今一度確認してみます!ありがとうございます!
guest

0

基本的にデータベースに画像は保存しない方がいいです
SQLで画像データいじるなんてしません
逆にデータベース云々抜きにして画像をどうこうしたい場合はあります

画像の中身に応じてサーバー側の処理を分岐なんてそうそうしないはずです

SQL側で画像が不要な場合や不要な行は取り出さないように
っていうのを徹底しないとメモリの負荷が半端なくなります
それでなくてもサーバー側の処理が画像のデータを
全部読み込むまでストップしちゃいます

データベースに画像を入れる方が色々スムーズと言えるのは
プログラムで動的にQRコードやアイコン程度のサイズの画像を
生成する場合ぐらいと思います

投稿2017/06/21 06:48

編集2017/06/21 06:51
KazuhiroHatano

総合スコア7804

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/21 08:44

貴重なご意見、誠にありがとうございます! やはり、保守管理面・サーバーへの負担を考えると、 後々構築者への負担がとてつもなく大きくのしかかってきそうです。 ありがとうございます!
guest

0

私はどちらも一長一短だとはおもいますが、質問者さんの状況であれば、「データーベースには画像を保存しない」ほうをおすすめですね。
理由はリファレンスの多さの違いです。何か追加機能を実装しようとしたときに、RDBに保存する設計より、ファイルサーバーに格納するほうが圧倒的に情報は見つかりやすいと思います。ま、ケースバイケースですが。

RDBに保存するすたいるは後々トライするくらいでいいかと思います。

投稿2017/06/21 06:05

h_daido

総合スコア824

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/06/21 07:34

貴重なご意見、誠にありがとうございます! RDBは後々トライしてみたいと考えております! 今回の件も踏まえ、商品管理データーベースなどを構築するにあたって、 やはりRDBは必須になってきますでしょうか?
guest

0

もう解決してしまってますが・・

画像の更新・参照頻度が低ければDBに入れるのもアリだとは思います。
が、画像データを扱うとデータ量や転送量の問題があるので、外部に置くのが良いかなと思います。

自分なら、画像自体はS3に保存してしまって、DBにはそのS3のパスを保存しておく。
参照が多い場合はCDN経由で画像を表示出来るようにしておく。
等の選択をするかなぁと思います。

投稿2017/06/27 01:25

coffee

総合スコア139

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/07/04 06:14

coffee様 アドバイス、誠にありがとうございます。 お恥ずかしいのですが「S3」とはどのような意味になっているのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問