非構造化データをDBに保存するか、ディレクトリに保存するか。

## そもそも非構造化データとは？

特定の構造をもたないデータの集まり。文書・画像・動画・音声など、定型的に扱えないデータを指す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072159/1df78cd1-604e-f5ed-81ee-8632c4e23e08.png)

https://www.soumu.go.jp/johotsusintokei/whitepaper/ja/h25/html/nc113110.html



## 「SQLアンチパターン」の一部まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072159/808f887e-3982-1632-5da3-623d7c9ef7b0.png)



#### 非構造化データをBLOB列に格納するメリット
* 非構造化データはデータベースに格納されます。ロードする追加のステップはありません。ファイルのパス名が正しくないというリスクはありません。
* 行（レコード）を削除すると、非構造化データが自動的に削除されます。
* 非構造化データに対する変更は、変更をコミットするまで他のクライアントには表示されません。
* トランザクションをロールバックすると、非構造化データの以前の状態が復元されます。
* 行を更新するとロックが作成されるため、他のクライアントは同じ非構造化データを同時に更新できません。
* データベース・バックアップには、すべてのイメージが含まれます。
* SQL権限は、非構造化データおよび行(レコード)へのアクセスを制御します。

当たり前ですが、 __Databaseに格納するとDatabaseの機能を有効活用できる__ ということですね。

SQLアンチパターンでは、非構造化データ(イメージ)は「DB格納派」として、記述されていました。

#### (参考)BLOBの最大サイズについて
* BLOBの最大サイズはデータベース・ブランドによって異なりますが、ほとんどのイメージを格納するには十分です。すべてのデータベースでBLOBまたはそれに類似したものをサポートする必要があります。たとえば、MySQLは、最大16MBまたは4GBのデータを格納するMEDIUMBLOBおよびLONGBLOBデータ型を提供します。Oracleでは、LONG RAWまたはBLOBと呼ばれるデータ型がサポートされており、容量はそれぞれ2GBまたは4GBです。他のデータベース・ブランドでも同様のデータ型を使用できます。

## 「データベースに画像を格納したい時 (Qiita)」の一部まとめ

https://qiita.com/7coco/items/1706a561131363d2c418

#### ファイルパスを格納する場合のメリット
* データベースの容量を減らせる
* データベースのバックアップが短時間で終了し、バックアップファイル容量も小さくなる。
* 画像のプレビューや編集が容易になる

#### ファイルパスを格納する場合のデメリット
* データベース上で削除しても、ファイルパスの先のファイルは自動的には削除されない
* トランザクションが分離するため、「ファイルはもうないのに該当する行を参照できる」という瞬間が生まれる
* 行を削除しようとする操作をロールバックしたとき、先に画像を削除していた場合、画像だけが消えた状態になってしまう。
* データベースのバックアップツールだけでは、画像ファイルのバックアップが行えない
* SQL におけるアクセス権限 ( GRANT, REVOKE ) が画像ファイルにそのものに適用されない
* データベースにはファイルパスが正当な値であるかどうかがわからない ( アプリケーションコード頼みになる )

#### BLOB 型に格納する場合のメリット
* 誤ったファイルパスを格納するリスクがない
* 行の削除と同時に画像も削除される
* 画像の変更がコミットするまで他のクライアントには見えない
* トランザクションをロールバックすると、画像を以前の状態に復元できる
* 行の更新時はロックされるため、複数のクライアントが同時に画像を更新できない
* データベースのバックアップにはすべての画像が含まれる
* SQL におけるアクセス権限によって、行と画像へのアクセスを管理できる


#### BLOB 型に格納する場合のデメリット
* 画像ファイルを BLOB列に読み込むための方法が必要 ( 一部データベース製品では外部ファイルをロードする関数を提供している )
* ファイルパスと比べ、容量が大きくなる
* ファイルパスと比べ、バックアップに時間がかかり、データベースのバックアップファイルが大きくなる



## 以下のサイトの一部まとめ

https://the-simple.jp/characteristics-of-blob-data-type-and-database-management-information-for-database-administrators

BLOBデータ型を扱う上で、データベース管理者が気をつけるべき点は、以下のようなものがあります。

1. バックアップの注意点
BLOBデータ型には、大量のデータを保存するため、バックアップ時の容量が増えるという問題があります。また、BLOBデータ型は、検索がしにくいため、一緒にバックアップする必要があるかどうかを考える必要があります。

2. インデックスの注意点
BLOBデータ型は、検索がしにくいという特徴があるため、インデックスを使用した検索が行えません。しかし、データベース管理者は、BLOBデータ型を検索可能なテキスト形式で保存することができます。その際には、インデックスを使用して検索することができます。

3. メモリの注意点
BLOBデータ型を扱う際には、メモリの使用量が増えることがあるため、十分に注意する必要があります。データベース管理者は、システムの容量を計画し、必要に応じてメモリの増設を行う必要があります。

メモリは特にREDOログバッファのサイズを気にした方が良いようです。



## Oracleの機能


https://www.oracle.com/jp/a/tech/docs/advanced-compression-poc-insights-ja.pdf

https://www.oracle.com/technetwork/jp/database/features/secure-files/securefiles-whitepaper-2009-160970-ja.pdf

seceure fileを使って格納すれば、セキュリティ担保出来るのとコストを抑えることができる


## Oracle Database 23cの新機能①

https://www.oracle.com/jp/news/announcement/ocw-integrated-vector-database-augments-generative-ai-2023-09-19/

* 「AIベクトルサーチ」という機能が追加されると発表されています。（2023/09/19時点）

* Oracle Databaseが文書、画像、その他非構造化データをベクトルとして格納し、これを活用して迅速な類似性クエリを実行することが可能となります。

* ベクトル検索を使うことで非構造化データを検索しやすくなりますので、このような技術を今後使いたいという方はDB格納をおすすめします。



## Oracle Database23cの新機能②

https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/cloud-operations.html#GUID-185F7862-2715-4EF4-A031-F9167D353E25

「Read-Only Tablespace on Object Storage」という機能です。

一定期間経過して更新しなくなった履データ（非構造化データ）を含む表領域をObject Stoargeへ簡単に移動してしまえます。

よって、非構造化データの保存にかかっていたコストを削減することが出来ます。


## 自分なりのまとめ
昔はDB内のBLOB型の検索機能が乏しかったが、検索機能はパワーアップした。
メモリに関しても大きい容量のメモリが出てきているので、サイズを気にすれば問題ないのではないか。
トランザクションとデータ保護の観点を重要視するならばBLOBでDBに保存し、許容できるのであればDB外に保存することも良い。

ただ、動画のような重いものだとDB格納では性能が出ないことが多いみたいです。そのような場合はオブジェクトストレージ格納など別の方法を検討すべき。