Realmデータベース_Swift3.0 肥大化したファイルの最適化

#Realmデータベース_Swift3.0 肥大化したファイルの最適化
こんにちは。フリーランスエンジニアの永田大祐です。
11月からは、保守運用のSwift言語の業務からSwift言語の新規案件プロジェクトに参画します。

今後もこのように情報を発信していきますので、よろしくお願いします:smile:

今回でRealmデータベースをモデルにした記事も三回目になりますが、なぜRealmをモデルにしているかと言いますと、iosのプログラム言語を覚える手段としても、Realmデータベースを使用すると、構造体やクラスの作成、継承といった考え方が学べると思いまして、Realmをモデルとして紹介させていただいております。またターミナル操作を覚えると作業がしやすくなると思いますので、合わせて紹介させていただきます。

[今回の検証サンプル](https://github.com/daisukenagata/RealmSample_Swift3.0/tree/Multithread_Bloated)

[前回の記事　Realmデータベース_Swift3.0　Carthageを使用して、ローカル内でマルチスレッドを使用する。](http://qiita.com/daisukenagata/items/b4ae43700bec50a7bdd3)

今回の内容は
#肥大化したFileの最適化

肥大したFileとは
[Realm公式サイト ファイルサイズと中間データについて](https://realm.io/jp/docs/swift/latest/#section-40)

SQLiteなどにデータを保存した時より、ディスクの使用容量が少なくなることを期待されることかと思います。
Realmファイルの容量が考えているよりも大きい場合は{{ RLMRealm }}は古い履歴データを残している可能性があります。

データの一貫性を保つために、Realmは最新のデータにアクセスしたときのみ履歴をアップデートします。
このことは、別のスレッドが多くのデータを長い時間をかけて書き込んでいる最中にデータを読み出そうとした場合、履歴はアップデートされずに古いデータを読み出すことになります。結果として、履歴の中間データが増加していくことになります。
この余分な領域は、最終的には再利用されるか消去されます。

####☝️一つの方法として、こちらの検証方法を紹介します。

##データベースの使用容量を調べる

1.アプリケーションに、一度にデータ容量が増える状況を作る。
2.データ容量を確認するため,[Realmブラウザーを使用する。](https://itunes.apple.com/jp/app/realm-browser/id1007457278?mt=12)
3.RealmのURLを確認する。
4.ターミナル操作でRealmFileを作成する。
5.検証結果を確認する。

###1.アプリケーションに、一度にデータ容量が増える状況を作る。
今回は100万回の文字列を入力します。

想定できる要件は顧客情報や、容量の多いNSDataを格納する際に、検証できる内容と思います。

	func Done(sender : UIButton){
		//同時にボタンを押したときなども非同期でスレッド取得、順番を制御する。
		DispatchQueue.main.async { () -> Void in
			if self.textSet.text! != ""{
				//数値設定
				self.clearSuti()
				//キーボードを下げ
				self.textSet.resignFirstResponder()
				try! realmTry.write {
					//配列に値を渡す
					for _ in 1...1000000{
					let now = NSDate()
					let object = [now,self.textSet.text!] as [Any]
					//realmfileに値を入れる
					realmTry.create(realmDataSet.self,value: object)
						let proRealm = realmSusiki()
						totalCount += proRealm.magnification
						self.totalTax.text? = totalCount.description
					}
					self.tableViewSetting.reloadData()
				}

ボタンが押された場合に、100万回データベースに入力しているだけです。


<img width="376" alt="スクリーンショット 2016-10-23 19.12.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/0169897d-c6ae-f0ea-7470-ee75c7a649be.png">

##2.データ容量を確認するため,[Realmブラウザーを使用する]
[Realmブラウザー](https://itunes.apple.com/jp/app/realm-browser/id1007457278?mt=12)をダウンロードしてください。



##3.RealmのFilePathを確認する。
今回は入力された時にこちらのメソッドを書きました。
Swift3.0のコードになります。

Realmを宣言する際に、RealmFileというものが必ず生成されます。
RealmFileのFileURL、FilePathを出力する方法です。

デフォルトで出力したURLの最後のPath、default.realmを f1.realmに書き換えてRealmFileをコピーしています。

				//Realmを生成時に自動で作られるURL
				let congig = Realm.Configuration.defaultConfiguration
				let realmFileURL = congig.fileURL
				//RealmFileの最後のpathを変更
				let copyFileURL = realmFileURL?.deletingLastPathComponent().appendingPathComponent("f1.realm")
				
				do {
					//RealmFileを呼び出す
					let realm = try Realm(configuration: congig)
					//RealmFileのコピーを呼び出す
					try realm.writeCopy(toFile: copyFileURL!)
				} catch {
					
				}
				print("デフォルトFilePath",congig)
				print("コピーしたRealmFile",copyFileURL!)

<img width="896" alt="スクリーンショット 2016-10-23 19.09.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/bb3ea3e3-1561-b03c-a270-09084dce6dc5.png">

コンソールにFilePathが出力されました。こちらのFilePathを使用します。



##4.ターミナル操作でRealmFileを作成する。
フォルダの作成

    $ mkdir RealmFile

ディレクトリーの指定　

    $ cd desktop/RealmFile

Pathの確認

    $ pwd
 
自分の環境ではこちらになります。(pwdで出力されたFilePathになります。)
   
    /Users/nagatadaisuke/desktop/RealmFile

Fileのコピー
   
    $ cp


###RealmFileを指定したフォルダ内にコピーします。自分の環境では、こちらをターミナルにペーストしてエンターで実施できます。
    $ cp /Users/nagatadaisuke/Library/Developer/CoreSimulator/Devices/2BB74A59-8A9C-4C3D-8542-C0000FBF0AFC/data/Containers/Data/Application/DBA19160-E559-4AD6-A5BE-9E3DBF1217ED/Documents/default.realm(スペース一つ)/Users/nagatadaisuke/desktop/RealmFile

f1.realmはdefault.realmのパス名を変更するだけです。


###5.検証結果を確認する。
今回はdefault.realmとf1.realmを使用します。
同じ100万件の文字列を入力しまたが、データ容量は最適化されました。
default.realmが167.8MB、f1.realmが12.6MBの結果でした。

<img width="206" alt="スクリーンショット 2016-10-23 20.31.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/7d62744f-08d6-7665-b6fc-7cdb143123bc.png">

<img width="436" alt="スクリーンショット 2016-10-23 20.33.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/d5f1be6e-eb72-a7c4-5dd1-de3f8d28192c.png">


<img width="789" alt="スクリーンショット 2016-10-23 19.35.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/86b5c9b2-d6fe-018f-fb37-c63919630c2c.png">

#まとめ

検証するための一つの技法を紹介させていただきました。
着目する点は、Realmのデータ使用量の確認方法、ターミナルでの操作、FilePathの操作だと思います。
FilePathを意識して作業をすると、より階層の深いところまで確認ができるようになりますので、合わせて参考にしていただけると幸いです。

今後もRealmブラウザーは重宝すると思います。
次回は、マイグレーション対応を紹介させていただきます。

貴重な時間を割き、お読み下さいましてありがとうございました。😀