20200322のMySQLに関する記事は2件です。

【Rails】データベース関連の知識、操作方法

はじめに

Railsでアプリを開発するにあたって、データベース関連の設計、操作で色々苦労したので、自分の覚えの為にもまとめてみました。

環境

  • Ruby 2.5.1
  • Rails 5.0.7

そもそもデータベースとは

一定の形式で、「複数で共有、利用すること」と「検索、加工すること」を目的に整理されたデータの集まりの事を指す。プログラミングに限定された用語ではなく、日常生活で使う辞書等もデータベースみたいですね!

データベース種類

  • 階層型
  • ネットワーク型
  • リレーショナル型(RDBと呼ばれ最も主流)
    • Oracle Database
    • MySQL
    • PostgreSQL
    • Microsoft SQL Server など
  • NoSQL

MySQLを使って開発する事が多かったので、ここからMySQL(リレーショナル型)に絞って話を進めていきます。

リレーショナルデータベース(RDB)、SQLとは

RDBは現在主流のデータベースで、エクセルみたいな表で構成されたデータベース。行と列を持ち、表形式でデータの関係性を示す。SQLを用いたデータのアクセスが可能。

SQL・・・Structured Query Languageの略で、リレーショナルデータベース(RDB)の操作を行うための言語。日本語訳は「構造化された問い合わせ言語」みたいな感じですかね!とにかくデータベースから情報を参照する言語。

データベース設計で意識する事

正規化、アソシエーション、制約の話をまとめていきます。

正規化

正規化・・・データベースのデータ構造をより効率的で重複や無駄のないシンプルな構造にするための手順。正規化の話は複雑ですが以下例です。
×予約情報が重複している為望ましくない
UNADJUSTEDNONRAW_mini_1a.jpg
○テーブルを2つに分け予約情報の重複を解消
2020-03-21 11.44のイメージ.jpg

アソシエーション

アソシエーション・・・テーブル間の関係性をモデルの上の関係として操作できるようにする仕組み。
アソシエーションを利用すると複数のテーブルにまたがるデータ操作もより直感的に利用できる。
【モデルへの書き方】

〇〇.rb
      # 1対多
      has_many :モデル名複数形
      # 多対1
      belongs_to :モデル名単数形
    # 1対1 どちらかのモデルにhas_one,もう一方にbelongs_to
      has_one :モデル名単数形
      belongs_to :モデル名単数形
      # 多対多 中間テーブルが必要
      has_many :中間テーブル名複数形
    has_many :モデル名複数形 through: :中間テーブル名複数形

制約による安全性

制約とは・・・特定のデータの保存を許さない事。例えば同じニックネームのユーザーを登録できないようにする、名前のデータが空のユーザーを保存を許さない等。主な制約は以下です。

制約種類

  • NOT NULL制約・・・空(nil)レコードは保存できない。
  • 一意性制約 ・・・同じ値を設定できない。一意性制約をかけるときは、インデックスの作成も必要。 全てのデータを検索しないと、過去のデータと重複しているか判断できない為。
  • 主キー制約 ・・・Railsでは主キーはidカラムとして自動で作成(テーブルの一番左のカラム)。
  • 外部キー制約 ・・・外部キー制約は、外部キーの対応するレコードが必ず存在しなくてはいけないという制約です。外部キーのカラムに値があっても、その値を主キーとして持つ他のテーブルにレコードが存在する必要あり。
create_users.rb
      # NOT NULL制約 nameはカラム名,stringはデータ型
      t.string :name, null: false
      # 一意性制約 インデックスとセット usersはテーブル名、emailはカラム名、stringはデータ型
      add_column :users, :email, :string
      add_index :users, :email, unique: true
      # 外部キー referencesはデータ型 これでuser_idというカラムが生成される
      t.references :user, foreign_key: true

データ型種類

  • string : 文字列
  • text : 長い文字列
  • integer : 整数
  • float : 浮動小数(実数)
  • datetime : 日時
  • time : 時間
  • date : 日付
  • boolean : Boolean

Railsでのコマンド集

ターミナル/マイグレーションファイル
  <データベース全般>
   #データベース作成(色んなテーブルを入れる箱の作成) database.ymlの内容に基づく
   rails db:create
   #データベース削除
   rails db:drop
   #マイグレーションファイルの適用
   rails db:migrate
   #マイグレーションファイルがどこまで適用されているか確認
   rails db:migrate:status
   #マイグレーションのバージョンを下げる デフォルトでは一つずつ
   rails db:rollback
   #マイグレーションのバージョンを複数下げる 例では3段階
   rails db:rollback STEP=3

   <モデル(テーブル)関連>コマンドでマイグレーションが作成されるので、そこで編集等を行う
   #モデル(テーブル作成) モデル名は単数形/頭文字を大文字にする
   rails g model モデル名

   #最初からカラム付きでモデルを作成したい時,2行目は例
   rails g model モデル名 カラム名:型
   rails g model User name:string email:string

   #既存のモデル(テーブル)にカラムを追加/削除,2行目は例
   rails g migration <マイグレーションファイル名> <追加するカラム名:型>
   rails g migration add_email_to_users email:string
   #以下マイグレーションファイル(add付きのファイル名でもカラムの削除は行える)
   # 追加(2行上のコマンドであればマイグレーション作成時からある)
   add_column :users, :email, :string
   # 削除(必要に応じて追加)
   remove_column :users, :gmail, :string
   # まとめて削除(必要に応じて追加)
   remove_columns :users, :column_1, :column_2 [, ...]
   # 追加する場所を指定する場合(必要に応じて追加)
   # 以下、nameカラムの直後にemailカラムを追加する場合
   add_column :users, :email, :string, :after => :name

   #指定のテーブル削除,2行目は例
   rails g migration Dropテーブル名
   rails g migration DropUser

   #既存のテーブル名を変更する,2行目は例
   rails g migration Rename変更前テーブル名To変更後テーブル名
   rails g migration RenameUserToCustomer

   #既存のカラムの内容を変更(例.Userモデルのemailカラムに制約をつける場合)
   rails g migration ChangeColumnToUser
   #以下マイグレーションファイル
  # 変更内容
   def up
     change_column :users, :email, :string, null: false
   end

   # 変更前の状態
   def down
     change_column :users, :email, :string, null: true
   end

その他の便利なメソッド

外部キー制約が要因で特定のレコードを削除できないエラーが起きる事があると思います。その時はdelete, delete_all, destroy, destroy_allメソッドが大変便利です。

こちらの記事が大変参考になりました。
https://qiita.com/kamelo151515/items/0fa7fb15a1d2c1e44db2

参考URL

https://qiita.com/kamelo151515/items/0fa7fb15a1d2c1e44db2
https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails アプリを EC2 にデプロイしよう!(デプロイ編)

Rails アプリを Amazon Web Service を使ってデプロイするまでの手順をまとめました。
次の順番でデプロイまで持っていきます。

1, 準備編
2, サーバー構築編
3, 環境構築編
4, デプロイ編

今回は「デプロイ編」です。
1 ~ 3 を読んでない方は先に読んでください。
Rails アプリを EC2 にデプロイしよう!(準備編)
Rails アプリを EC2 にデプロイしよう!(サーバー構築編)
Rails アプリを EC2 にデプロイしよう!(環境構築編)

Gem のインストール

前回までに、アプリのクローンを完了しました。
今回の最初の作業は、gem のインストールです。

まずは bundler を設定しましょう。
bundler は本アプリ使用している bundler とバージョンが一致しているものを選択しましょう。

[minato@ip-192-168-10-49 ~]$ /var/www/rails/sample_app
[minato@ip-192-168-10-49 sample_app]$ gem install bundler 2.1.4
Fetching bundler-2.1.4.gem
Successfully installed bundler-2.1.4
Parsing documentation for bundler-2.1.4
Installing ri documentation for bundler-2.1.4
Done installing documentation for bundler after 3 seconds
1 gem installed

次に、Gemfile の中身を確認しましょう。
今回は次の gem を想定しています。

Gemfile
gem 'rails', '~> 5.2.2'
gem 'bootsnap', require: false
gem 'puma', '~> 3.7'
gem 'mysql2', '>= 0.4.10', '< 0.5'

確認したら bundle install を行いましょう。

[minato@ip-192-168-10-49 sample_app]$ bundle _2.1.4_ install --path vendor/bundle --without development:test

無事にインストールできれば OK です。

アプリの secret_key_base の設定

次に secret_key_base の設定を行います。
今回は Rails 5.2 なので、config/credentials.yml.enc を読み込むために
config/master.key をEC2でも作成しましょう。
これがないと本番環境で起動することができません。

  1. ローカル環境 にある config/master.key の中身をコピーします。
  2. サーバー環境config/master.key を新規作成して先ほどコピーした内容をペーストします。

次のコマンドで secret_key_base が確認できれば OK です。

[minato@ip-192-168-10-49 sample_app]$ EDITOR="vim" bundle exec rails credentials:edit

Puma の設定

次は Puma の設定を行います。
Puma はアプリケーションサーバーの一種です。

早速設定していきます。

config/puma.rb
case ENV['RAILS_ENV']
when "production"
  environment "production"
  port 3000
  threads 16, 16
  daemonize true

  # sample_app の部分は自身のアプリケーションの名前に変更してください。
  app_dir = File.expand_path("/var/www/rails/sample_app", __FILE__)

  bind  "unix://#{app_dir}/tmp/sockets/puma.sock"
  pidfile      "#{app_dir}/tmp/pids/puma.pid"
  state_path   "#{app_dir}/tmp/pids/puma.state"

  stdout_redirect nil, "#{app_dir}/log/puma.stderr.log", true

  plugin :tmp_restart
else
  environment "development"
  port 3000
  threads 5, 5

  pidfile    "tmp/pids/puma.pid"
  state_path "tmp/pids/puma.state"

  stdout_redirect nil, "log/puma.stderr.log", true

  plugin :tmp_restart
end

ここら辺は設定ファイルなので、詳細には追いません。
また、設定ファイルの記述が終わったら、次のコマンドも実行してください。

[minato@ip-192-168-10-49 sample_app]$ mkdir tmp/sockets

puma.sock を作成先のディレクトリを作成しています。
これで Puma の設定が完了です。

Nginx の設定

お次は Nginx です。「エンジンエックス」と読むそうです。
この Nginx は Web サーバーにあたります。

早速下記コマンドを打ち込んでください。

[minato@ip-192-168-10-49 ~]$ cd ~
[minato@ip-192-168-10-49 ~]$ sudo yum install nginx
[minato@ip-192-168-10-49 ~]$ sudo vim /etc/nginx/conf.d/sample_app.conf

vim コマンドで作成した nginx の設定ファイルを次のように記述します。

/etc/nginx/conf.d/sample_app.conf
# アクセスログ・エラーログの出力先を設定する
# sample_app の部分は自身のアプリケーションの名前に変更してください
error_log  /var/www/rails/sample_app/log/nginx.error.log;
access_log /var/www/rails/sample_app/log/nginx.access.log;

upstream puma {
    # puma.sock の場所を指定する
    # sample_app の部分は自身のアプリケーションの名前に変更してください
    server unix:///var/www/rails/sample_app/tmp/sockets/puma.sock;
}

server {
    listen 80;

    # server_name を設定します。自身のパブリックDNSに変更してください。
    server_name ec2-52-198-194-39.ap-northeast-1.compute.amazonaws.com;

    client_max_body_size 500M;
    keepalive_timeout 5;

    # パブリックページの場所をここで設定します。
    # sample_app の部分は自身のアプリケーションの名前に変更してください
    root /var/www/rails/sample_app/public;

    location / {
        try_files $uri $uri/index.html $uri.html @app;
    }

    location @app {
        proxy_read_timeout    300;
        proxy_connect_timeout 300;
        proxy_redirect        off;
        client_max_body_size  1G;

        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;

        proxy_pass http://puma;
    }

    # Rails のエラーページを表示する
    # sample_app の部分は自身のアプリケーションの名前に変更してください
    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /var/www/rails/sample_app/public;
    }
}

ここも設定ファイルなので詳細には追いません。
また、AWSが生成するドメイン名が
ec2-52-198-194-39.ap-northeast-1.compute.amazonaws.com
と大変長いので、次のコマンドを実行して設定を変えます。

$ sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old
$ sudp vim /etc/nginx/nginx.conf
nginx.conf
# ...

http {
    # ...
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    server_names_hash_bucket_size 128; # これを追記
    # ...
}

最後に、次のコマンドを実行してください。

[minato@ip-192-168-10-49 conf.d]$ cd /var/lib
[minato@ip-192-168-10-49 lib]$ sudo chmod -R 775 nginx

post メソッドでもエラーが出ないようにするためのものです。
これにて Nginx の設定完了です。

MySQLの設定

次は DB です。
アプリケーションの DB が MySQL で作成されている前提で話を進めていきます。

まずは database の設定を行います。

[minato@ip-192-168-10-49 sample_app]$ vim config/database.yml

設定内容は次のとおりです。

config/database.yml
production:
  <<: *default
  adapter: mysql2
  port: 3306
  database: sample_app_production
  username: root
  password:
  encoding: utf8
  charset: utf8
  collation: utf8_general_ci

保存したら次のコマンドを実行していきましょう。

# mysql を起動
[minato@ip-192-168-10-49 sample_app]$ sudo service mysqld start

# mysql.sock を /tmp に移動する
[minato@ip-192-168-10-49 sample_app]$ ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock

# 本番環境用の db を作成する
[minato@ip-192-168-10-49 sample_app]$ RAILS_ENV=production bundle exec rake db:create

# 本番環境用の db の migrate を実行する
[minato@ip-192-168-10-49 sample_app]$ RAILS_ENV=production bundle exec rake db:migrate

seed を予め設定する場合はこのタイミングで実行してください。

Rails アプリの起動

このコマンドで puma を起動しましょう。
これで Rails アプリが起動します。

[minato@ip-192-168-10-49 sample_app]$ RAILS_ENV=production bundle exec puma

インターネットからアクセス出来る様に
次のコマンドで nginx を起動します。

[minato@ip-192-168-10-49 sample_app]$ sudo service nginx start

自身のパブリックDNSを使用してブラウザからアクセスしてみましょう
http://ec2-52-198-194-39.ap-northeast-1.compute.amazonaws.com/

無事にアクセスできれば OK です。

停止方法

最後に停止方法について記述しておきます。

$ sudo service nginx stop
$ bundle exec pumactl halt

最後に

これでデプロイを完了することができました。

でも、まだアクセス出来てない方もいるかと思います。
そんな方はググったり、質問したりして問題解決を頑張ってください。
当たりが強いエンジニアもいますが、優しく教えてくれるエンジニアもいます。

自分は大学一回生でこのデプロイ作業を初めて行いましたが、完了するのに1週間もかかりました。
それでも大学の先輩に質問したり、頑張って英語の公式ドキュメントを読んだり、
ひたすらググったりすることでなんとかデプロイを完了しました。

このデプロイ経験で多くの知識や経験を得ました。
特に、根気よく問題解決する精神は鍛えられました。

根気よく、適度に休憩をとりながら、デプロイ作業を頑張ってください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む