Laravelのドキュメントを読み解く 〜データベース〜

# 前提
- WindowsでLaravelを使うための基本知識についてまとめています
- リファレンスなどをもとに学習したことを自分が理解しやすいように直してまとめています
- Laravel5.4のリファレンスをもとにしています
- まとめの粒度や順番は主観によるものです。省略している部分もあります

# 概要
- Laravelはデータベースの扱いがとても簡単にできるフレームワークです
- この記事ではLaravelを使った基本的なデータベースの扱い方についてまとめています

# データベースの準備
## 設定
- Laravelでデータベースを扱う場合、下記の設定変更が必要です
	- [Laravelでの開発の初期設定について](http://qiita.com/yunomi/items/682946d04a55c98c1036#laravel%E3%81%AE%E8%A8%AD%E5%AE%9A%E5%A4%89%E6%9B%B4)

## トランザクション
- Laravelを使ったトランザクションは下記のように行います。トランザクションはユーザーの資産に関連するものを増減させたりする場合に行う必要があります。

		// トランザクション（1回）
		DB::transaction(function () {
		    DB::table('users')->update(['votes' => 1]);
		
		    DB::table('posts')->delete();
		});

		// トランザクション（5回数試行を行う、試行回数過ぎても駄目だったらこの処理はなかったことになる）
		DB::transaction(function () {
		    DB::table('users')->update(['votes' => 1]);
		
		    DB::table('posts')->delete();
		}, 5);

- 参考（トランザクションとは）
	- http://wa3.i-3-i.info/word142.html
	- http://wa3.i-3-i.info/word143.html

## スレーブ/マスターの設定について
- http://qiita.com/dev-ikeda/items/d74b51d9367c0759210b
- http://qiita.com/sasakure-kei@github/items/bd4f64bae860e7287b8f

# クエリービルダー
- 概要
	- Laravelにはデータベースの操作方法としてクエリービルダーとEloquentの2種類があります
	- Eloquent(Modelを使った方法)の方が記述が楽ですが速度が遅いようです
		- http://blog.comnect.jp.net/blog/102
- 記述方法

		// usersテーブルの全レコードを取得する例(getメソッドはIlluminate\Support\Collectionを返す)
		$users = DB::table('users')->get();
		foreach ($users as $user) {
		    echo $user->name;
		}
		
		// 1レコードだけ取得したい場合の例
		$user = DB::table('users')->where('name', 'John')->first();
		echo $user->name;


- クエリービルダーで使えるメソッド
	- 集計系

			// メソッド
			count、max、min、avg、sum
			
			// 使用サンプル
			DB::table('orders')->count();	

	- SQL
		- SELECT

				$users = DB::table('users')->select('name', 'email as user_email')->get();

		- JOIN(INNER JOIN)

				$users = DB::table('users')
				            ->join('contacts', 'users.id', '=', 'contacts.user_id')
				            ->join('orders', 'users.id', '=', 'orders.user_id')
				            ->get();

		- UNION

				$first = DB::table('users')
				            ->whereNull('first_name');
				
				$users = DB::table('users')
				            ->whereNull('last_name')
				            ->union($first)
				            ->get();		
						
		- WHERE
				
				$users = DB::table('users')->where('votes', 100)->get();
				$users = DB::table('users')->where('votes', '>=', 100)->get();
				$users = DB::table('users')->where('votes', '>', 100)->orWhere('name', 'John')->get();
				$users = DB::table('users')->whereBetween('votes', [1, 100])->get();
				$users = DB::table('users')->whereNotBetween('votes', [1, 100])->get();
				$users = DB::table('users')->whereIn('id', [1, 2, 3])->get();
				$users = DB::table('users')->whereNotIn('id', [1, 2, 3])->get();

		- orderBy（降順、昇順）

				$users = DB::table('users')->orderBy('name', 'desc')->get();
				$users = DB::table('users')->orderBy('name', 'asc')->get();

		- groupBy（レコードのグループ化）

				$users = DB::table('users')->groupBy('account_id')->get();

		- レコード取得の制限

				$users = DB::table('users')->limit(5)

		- 増減

				DB::table('users')->increment('votes');
				DB::table('users')->increment('votes', 5);
				DB::table('users')->decrement('votes');
				DB::table('users')->decrement('votes', 5);

		- 増減操作と同時に更新

				DB::table('users')->increment('votes', 1, ['name' => 'John']);

		- 削除

				DB::table('users')->where('votes', '>', 100)->delete();

# ページネーション
- 概要
	- 同じような項目（商品リストなど）が羅列される内容のページを作る時にページ分割を行うことができる機能です

- 記述サンプル

		// コントローラ側
		public function index()
		{
			// 通常ページ分割バージョン
		    $users = DB::table('users')->paginate(15);

		    // 前と後のみの分割バージョン
		    $users = DB::table('users')->simplePaginate(15);
		    
		    // モデルを使ったバージョン
		    $users = App\User::paginate(15);
		
		    return view('user.index', ['users' => $users]);
		}
		
		// ビュー側
		<div class="container">
		    @foreach ($users as $user)
		        {{ $user->name }}
		    @endforeach
		</div>
		
		{{ $users->links() }}		


# マイグレーション
- 概要
	- マイグレーションとはデータベースのバージョンコントロールのような機能です
	- テーブル内容の記述については下記のSequelPro用プラグインの利用がオススメです
		- http://co.bsnws.net/article/203

- マイグレーションの使い方
	- 基本知識
		- public function up()欄には変更を加える内容を記述します
		- public function down()欄には変更を戻すための内容を記述します
	- マイグレーションファイルの新規作成
		- マイグレーションファイルはなるべくモデルと一緒に作成します（単一でも作成は可能）

				// モデルと合わせて作成する場合（モデル名はパスカルケースで単数表記を推奨）
				php artisan make:model モデル名 --migration
				
				// 単一で作成する場合（テーブル名はスネークケースの小文字で複数表記を推奨）
				php artisan make:migration create_テーブル名_table --create=テーブル名

	- マイグレーションファイルの修正（テーブル構造の修正）
		- コマンド

				php artisan make:migration hoge_テーブル名_table --table=テーブル名
		- 修正内容の記述について
			- https://readouble.com/laravel/5.4/ja/migrations.html


	- マイグレーションファイルの実行/巻き戻しなどのコマンド

			// ファイルの実行
			php artisan migrate
			
			// ロールバック(1段階の場合はオプションコマンドは不要)
			php artisan migrate:rollback --step=5
			
			// マイグレーションファイルの状況を確認
			php artisan migrate:status



# シーディング
- データベースに仮のデータを入れるためのLaravelの機能です
- シーダーファイルの作成フロー
	1. 作成

			// シーディングファイルの名称はパスカルケースで複数表記を推奨
			php artisan make:seeder [テーブル名]TableSeeder

	1. ファイルの記述（サンプル）

			// サンプル
			// テストデータに日本語が入ってくる
			$faker = Faker\Factory::create('ja_JP');
			
			for ($i = 0; $i < 10; $i++) {
			    App\[モデル名]::create([
			        'uuid' => $faker->text(32),
			        'created_at' => $faker->dateTime('now'),
			        'updated_at' => $faker->dateTime('now'),
			    ]);
			}

	1. DatabaseSeederに実行コードを記述

			public function run()
			{
			    $this->call(UsersTableSeeder::class);
			    $this->call(PostsTableSeeder::class);
			    $this->call(CommentsTableSeeder::class);
			}

	1. シーダーファイルの実行

			// DatabaseSeederを実行する
			php artisan db:seed
	
			// 特定のクラスのシーダーのみを実行する場合
			php artisan db:seed --class=実行するシーダークラス名

# Redisについて
- 概要
	- RedisとはRDBMSと呼ばれるMySQLなどのExcelのようなデータベースではなく、NoSQLと呼ばれるKVS系のデータベースです。
	- MySQLなどと違い、KeyとValue(1:1の関係)のものしか扱うことができない。しかしその反面、速度がすごく早いのが特徴です。
	- Redisは失っても問題がない値。値が頻繁に削除や更新がされない。高速な読み書きが必要なデータを格納するのに適していると考えられます。アプリの場合、マスターデータのキャッシュ用としてとても相性が良いのが特徴です。
	- NoSQLと呼ばれるタイプのデータベースはいろいろありますが、LaravelではRedisが簡単に使えるように用意されています。

- キャッシュについて
	- 同じものを何度も取得するのは無駄である。そのためマスタなどのように更新がかかるようなものでないものに対しては結果をキャッシュして使うようにする。

- 前提準備

		composer require predis/predis

- 設定

		'redis' => [
		
		    'client' => 'predis',
		
		    'clusters' => [
		        'default' => [
		            [
		                'host' => env('REDIS_HOST', 'localhost'),
		                'password' => env('REDIS_PASSWORD', null),
		                'port' => env('REDIS_PORT', 6379),
		                'database' => 0,
		            ],
		        ],
		    ],
		
		],

- 参考サイト
	- NoSQLとは
		- https://academy.gmocloud.com/qa/20160509/2284
	
	- phpRedisAdmin
		- https://github.com/ErikDubbelboer/phpRedisAdmin
	
	- Rediesの使い時
		- http://co.bsnws.net/article/64

# バックナンバー
- Laravelのドキュメントを読み解く 〜開発準備〜
	- http://qiita.com/yunomi/items/682946d04a55c98c1036