GPT先生と学ぶ📸画像はDBよりストレージに置こう!
はじめに (by もも 🍑 (ᐢ ˙꒳˙ ᐢ)💗)
この記事はこんな人に読んでほしい!
- 画像ファイルを PostgreSQL の
bytea
に突っ込もうとしてるエンジニアさん - GCS/S3 など オブジェクトストレージのメリットを知りたい人
- 「結局どっちが速いの?💢」と夜中にググってるあなた ⭐️
私も開発中に「画像って DB に直接保存しちゃダメなん?😳」って疑問が止まらず、深夜テンションで せんぱい 👴🏻(社内で“おぢさん”と呼ばれてるベテラン 🧑🏻💻)に質問攻めしちゃいました ❣️
もも 🍑 × せんぱい 👴🏻 💬 フランク Q&A
⚠️ もも 🍑 の思考プロセスをそのまま載せるスタイルです。長いけどリアル!
1️⃣ 拡張子って何してるの?
もも 🍑: 画像の拡張子って何? 25×25×4 バイトより小さくなるのはどうして?
せんぱい 👴🏻: 拡張子はフォーマット(PNG/JPEG/WebP)を示すだけ。本体は 圧縮アルゴリズム が頑張ってる。未圧縮 RAW は 2.5 KB だけど、JPEG が "見えにくい情報" を削って数百バイトにするイメージ。
2️⃣ 圧縮の意味って? 規則性を省略?
もも 🍑: 圧縮できる理由がピンと来ないんだよね…規則性を見つける感じ?
せんぱい 👴🏻: Exactly。そのとおり! 🎯 連続した同色を RLE で「赤 ×8」みたいに短縮したり、JPEG は DCT で「人が気づかない高周波」を捨てる。冗長性を抜く=サイズ減!
3️⃣ ストレージ保存と DB 保存、違いは?
もも 🍑: じゃあ画像をストレージと DB に保存するの、何が違う?バイナリなら一緒じゃ?
せんぱい 👴🏻:
- ストレージ (GCS/S3) → ファイル単位、CDN 配信 ◎、大容量前提。
-
DB (
bytea
) → 行データの一部。数 MB 超えるとクエリ激重、バックアップ遅い。
結論: ファイルはストレージ、DB には URL だけ!
4️⃣ PostgreSQL は画像に向かないの? GCS はなぜ強い?
もも 🍑: PostgreSQL の実装が画像向きじゃないって? 逆に GCS が適してる理由は?
せんぱい 👴🏻:
-
bytea
は 行全体を RAM に展開→ 大容量だとメモリ&I/O 地獄 💢。 - GCS は 分散 FS。巨大ファイルでもストリーミング転送でメモリ最小。
5️⃣ 「ファイルとして保存=制約なし」とは?
もも 🍑: ファイルも結局バイナリじゃ? バイナリ以外って保存できる?
せんぱい 👴🏻: ファイル=バイナリだけど、管理単位 が違う。ストレージは「名前+バイト列」を丸ごと扱う。DB は行・列の中に押し込む。文字列(Base64)保存もできるけど 33%サイズ増はつらい 🤣。
6️⃣ 「bytea はインメモリ処理」って?
もも 🍑: bytea は RAM 展開ってどういう仕組み? GCS は何が違う?
せんぱい 👴🏻: SELECT image FROM photos …
時、DB は TOAST 圧縮を解凍 → 全バイトをバッファに読込。GCS はクライアントに ストリームで少しずつ 送る。メモリ消費が段違い!
7️⃣ まとめ認識チェック 💡
もも 🍑: つまり…
PostgreSQL で巨大 bytea
は効率悪い。
GCS はファイルオブジェクトで大容量&ストリーミング OK。
で合ってる?
せんぱい 👴🏻: 💯 パーフェクト!
🚀 Key Takeaways
✅ やること | ❌ やらないこと |
---|---|
ストレージに画像を置き、URL を DB に保存 | 画像を丸ごと bytea に突っ込む |
CDN/Signed URL で高速&安全配信 | DB バックアップに BLOB を混在させる |
超重要まとめ
PostgreSQL の DB カラムにバイナリを bytea
型で保存 → 効率が悪い(巨大な bytea
の処理に最適化されていない)
GCS などのオブジェクトストレージに ファイルオブジェクト(ファイル名+バイナリ) として保存 → 効率が良い(大きいサイズを扱う前提、ストリーミング処理も可)
おわりに 💞
画像保存で悩むあなたへ:**「大きいものは大きい器に」**が鉄則。まずは GCS/S3 を触ってみてね ⭐️
一緒に開発楽しもうね!ばいばい ♡ (ᐢ ˙꒳˙ ᐢ)❣️
Discussion