『Ruby on Rails5速習実践ガイド』について少し理解を深めました。

皆様こんにちは、Amiaです。

私は1ヶ月くらいかけてタイトルにもある通り『Ruby on Rails5速習実践ガイド』(https://www.amazon.co.jp/dp/B00EE1XPAI)を読んでいました。
そのため今回は上記の書籍について読んだ感想等をまとめいきたいと思います。

よろしければ最後までご覧になっていただければと思います。

⚫︎良かった点

  • Rubyについても少し触れられているため学習したことの復習にもなった。
  • 図や表など使用して解説されているため、わかりやすい部分があった。

⚫︎学んだこと

「Chapter1 RailsのためのRuby入門」

  • インスタンス変数はオブジェクトの外側から直接利用することは基本的にできない。
  • Rubyではnilとfalseが偽、それ以外が真となる。
    • 真か偽という結果は、『==』などの実行結果だけでなくオブジェクトそのものを評価しても得られる。
  • 『&.(ぼっち演算子)』を使ってメソッドを呼び出すと、レシーバがnilであった場合でもエラーが発生しなくなる。

「Chapter2 Railsアプリケーションをのぞいてみよう」

  • MVC - ソフトウェアをどのような構造にするかについての考え方のパターンの1つ。UIに関わる部分(ビュー)と、アプリケーション固有のデータや処理の扱いの部分(モデル)、モデルやビューを統合的に制御する部分(コントローラ)の3つに役割を分けて管理しやすくする、というのがMVCの主な目的。
    • モデル - データとデータに関わるビジネスロジック(アプリケーション特有の処理)をオブジェクトとして実装したもの。データは多くの場合データベースで永続化されるが、データベースへの保存や読み込みもモデルが担当する。
    • ビュー - ブラウザに表示する画面(HTMLなどのHTTPレスポンスの中身)を実際に組み立てる部分。必要に応じてコントローラからモデルのオブジェクトを受け取り、画面表示に利用する。
    • コントローラ - ユーザーが操作するブラウザなどのクライアントからの入力(リクエスト)を受け、適切な出力(レスポンス)を達成するための制御を行う部分。必要に応じてモデルを利用したり、ビューを呼び出したりしてレスポンスを作り上げる。モデルとビューのコントロールを行う存在。
      • コントローラ層ではブラウザなどから発行されたHTTPリクエストの宛先となっているURLや、GETやPOSTといったHTTPメソッドをもとに『どのコントーラ(クラス)の、どのアクション(メソッド)が処理を担当するのか』をまず特定する。

「Chapter3 タスク管理アプリケーションを作ろう」

  • アプリケーションの作成には一般的に下記のような準備を行う。
    • 作成するアプリケーションの内容を考える。
    • アプリケーションの名前を決める。
    • アプリケーションの雛形を作成する。
    • データベースを作成する。
  • 下記のコマンドでアプリケーションの基本的なディレクトリ・ファイル類一式を作成する。
    rails new アプリケーション名 [オプション]
  • 下記のコマンドでデータベースを作成できる。
    bin/rails db:create
  • 下記のコマンドでサーバを起動できる。
    bin/rails server
    ※短縮系はbin/rails s
  • Railsでは下記のような3種類の環境が用意されており、1つの環境に対して1つのデータベースを対応させる。環境ごとにデータベースの他、アプリケーションの動作に関わる様々な設定を行うことができる。どの環境にどのようなデータベースを対応させるかは、『config/database.yml』に記述する。
環境の種類 環境のシステム名 用途
開発 development 開発時の動作確認を行う
テスト test 自動テストを行う
本番 production ユーザーが利用可能な形で稼働させる
  • モデル
    • モデルは主に下記の2つの要素から構成される。
      • モデルに対応するRubyのクラス
      • モデルに対応するデータベースのテーブル
    • モデルのクラス名とデータベースのテーブル名には下記のような命名の規約がある。
      • データベースのテーブル名はモデルのクラス名を複数形にしたもの。
      • モデルのクラス名はキャメルケース、テーブル名はスネークケース。
    • モデルを生成する場合のコマンドは下記のような構成になる。コマンドを実行すると、モデルのクラスファイル、マイグレーションファイル、モデルの自動テストのファイルの雛形が自動作成される。
      bin/rails g model [モデル名] [属性名:データ型 属性名:データ型 ...] [オプション]
生成されるものの種類 用途
モデルクラスのソースコード 生成されたクラスの実装
マイグレーションファイル データベースに作成されたテーブルを追加する
モデルの自動テスト 生成されたクラスについての自動テストの実装
モデルの自動テストで使う
fixtureファイル
生成されたクラスについての自動テストのためのデータ投入の定義
  • マイグレーション
  • 下記のコマンドを実行することでコントローラを作成する。
    bin/rails g controller コントローラ名 [アクション名 アクション名 ...] [オプション]
    • controllerのジェネレータでアクションを指定すると、アクションと同名のビューも一緒に作成される。
    • HTTPメソッドがGETのアクションは同名のビューを使うことが多いという法則があるため、HTTPメソッドがGETととなるアクション名をジェネレータコマンドの引数として指定するのが効率的。
  • コントローラのインスタンス変数は、ビューからも見ることができる。アクションからビューに受け渡しをしたいデータをインスタンス変数に入れることが、アクションの基本的な役割のひとつ。
  • リクエストパラメータ - リクエストにデータを添えること。
    • リクエストパラメータの送り方は、HTTPの仕組みの上で2通りに別れる。
      • POSTで送る。基本的にはHTMLのform要素をsubmitすることで送られる。
      • GETで送る。基本的にはURLの?以降に情報を含めることで送る。普通に?の付いたURLにブラウザからアクセスする他、form要素のmethod属性にgetを指定してform要素のsubmitを通じてそのようなリクエストを送ることもできる。
        上記2つの方法は送り方が違うため本来は受け取り方も異なるものだが、Railsプログラマが両者をなるべく区別しなくて済むようにしてくれる。具体的には、コントローラにおいてparamsというメソッドを利用することで、POSTかGETかに関係なく、送られてきたリクエストパラメータをHashのような感覚で取得することができる。
  • form_with - モデルオブジェクトを使ってHTMLのform要素を作成するためのメソッド。
  • モデルとフォームは、モデルの属性がフォーム内のフィールドに対応するという面で構造が似ている。
  • フォーム内部のHTMLは、form_withに渡すブロックの中に記述する。その際、ブロック引数に対してlabelやtext_field、text_areaなどのメソッドを呼び出すことで、モデルオブジェクトの属性に対応するフィールドを出力することができる。
  • レンダー - 一覧画面や新規登録画面を表示する際のように、アクションに続けてビューを表示させること。
    *リダイレクト - 登録処理後に一覧画面に遷移する際のようにアクションを処理した直後にビューを表示せず、別のURLに案内する動きのこと。
  • レンダーを行うにはrender、リダイレクトを行うにはredirect_toメソッドをそれぞれ使う。どちらを記述しない時は、アクションに対応する場所・名前のビューファイルをrenderする。
  • Flashメッセージ - redirect_toに渡すことができる。Flashは主にリダイレクトの際に、次のリクエストに対してちょっとしたデータを伝えるためにRailsが用意している仕組み。Flashには、ハッシュの形でデータを格納できる。

「Chapter4 現実の複雑さに対応する」

  • マイグレーションは基本的に下記の2ステップで行う。
  • マイグレーションは、1つのマイグレーション(ファイル)が1つのバージョンとして扱われる。
  • マイグレーションはデータベースごとに適用する必要がある。デフォルトでは開発用データベースに対してマイグレーションが実施される。
    bin/rails db:migrate
    本番用データベースにマイグレーションを実施したい場合はmigrateコマンドに『RAILS_ENV=production』を付ける。
    bin/rails db:migrate RAILS_ENV=production テスト用データベースにマイグレーションを実施したい場合はmigrateコマンドに『RAILS_ENV=test』を付ける。
    bin/rails db:migrate RAILS_ENV=test
  • Railsアプリケーションのデータベースではどこまでマイグレーションが当たっているかが自己管理されている。これはデータベース内に作成される『schema_migrations』というテーブルを通じて行われ、どのマイグレーション(バージョン)が適用ずみかをデータとして保存している。これによりrails migrateコマンドは、飛び石でマイグレーションが適用されているような状況でも、適用していないマイグレーションだけを適用して進んでくれる。
  • マイグレーションの名前は、アプリケーション内でアプリケーション内で一意である必要がある。そのため、『AddDeadlineToTasks』のような具体的な名前を付けるやり方が一般的である。
  • schema.rb
    • Railsは、現在のデータベースの構造を『db/schema.rb』というファイルに自動出力する。
    • このファイルは、マイグレーションを適用したり外したりすると自動的に出力される。
    • 『db/schema:dump』コマンドで手動で出力することもできる。
    • 『schema.rb』は自動テスト環境などで使用される他、視覚的にテーブル・カラム構造を確認できるため、データベースについての手軽なドキュメントとして利用することもできる。
  • マイグレーションに関する主なコマンド
コマンド 意味
bin/rails db:migrate 最新までマイグレーションを適用する。
bin/rails db:migrate VERSION=20180608051058 特定バージョンまでマイグレーションが適用された状態にする。VERSIONにはマイグレーションファイル名の先頭の数字部分(日時部分)を指定する。例えば、ファイル名が『20180608051058_create_tasks.rb』であった場合は『VERSION=20180608051058』とする。
bin/rails db:rollback バージョンを1つ戻す。
bin/rails db:rollback STEP=2 バージョンを指定したステップ数だけ戻す。
bin/rails db:migrate:redo バージョンを1つ戻してから1つ上げる。(バージョンは最終的に変化しないが、バージョンを戻す処理が想定通り動作することを簡単に確認できる。)
  • エラーでマイグレーションが中止された場合は、問題の起きたマイグレーションで適用しかけた変更はロールバックされ、それ以降のマイグレーションも適用されない。つまり、問題の起きたマイグレーションを適用する前の状態のままとなる。
  • データの内容の範囲
    • データ型 - データベースのカラムには型を指定する。型を指定することでデータの範囲を限定することができる。
    • NOT NULL制約 - NOT NULL制約を付けることで、物理的にNULLを保存できないようにしてくれる。
    • 文字列カラムの長さを指定する - データベースのカラム定義で文字列の長さを指定することで、必要以上に長いデータが保存されることを防ぐことができる。マイグレーションで文字列カラムに対して文字列の長さを指定するには、limitオプションを使う。
    • ユニークインデックス - あるテーブルのあるカラムのデータが(もしくは、複数のカラムのデータの組み合わせが)、全レコード内で一意である場合には、データベースにユニークインデックスを作成することで、一意性が壊されることを防ぐことができる。
  • データベースでは、NULL同士は常に異なる値だと見なされることに注意すること。
  • モデルの検証の仕組み
    • Railsにおけるモデルの検証は基本的に『モデルオブジェクト(レコード)をデータベースに登録・更新する前に検証を行い、エラーがあれば登録・更新しないで差し戻す』という仕組みになっている。
    • saveメソッド - データベースの登録・更新を行う前に自動的に検証を行い、検証エラーがあればfalseを返す。
      • 検証エラーの詳細には、errorsを通じてアクセスできる。
      • 検証エラーがなければ、データベースへの登録・更新を行なってtrueを返す。この時、検証失敗以外の予期せぬエラーがあれば例外を発生させる。
    • 検証は検証処理単独でも呼ぶことができる。それには『valid?』というメソッドを利用する。
    • save!メソッド - 検証エラー時にfalseを返すのではなく例外を発生させるメソッド。
      • save!を使った場合は、例外が出なければデータベースへの登録・更新が間違いなく行われたと考えることができる。
      • 基本的に登録・更新が成功するはずと信じている場面(検証エラーのハンドリングを行わない場面)では、saveよりもsave!を使ったほうが、予期せぬ失敗を防ぐことができる。
    • saveもsave!も登録・更新前に自動的に検証を行うが、その検証を意図的にスキップすることができる。それにはvalidate: falseというオプションをメソッドに渡す。
  • 検証の書き方 - プログラマがモデルの検証コードを書く方法には、大きく分けて下記の2通りがある。
    • Railsが用意している検証用のヘルパーを利用する。
    • ②自分で任意の検証コードを記述する。 - 書き方には下記の2通りがある。
      • 検証を行うメソッドを追加して、そのメソッドを検証用のメソッドとして指定する。
        • あるモデル専用の処理を手軽に書く場合に適している。
      • 自前のValidatorを作って利用する。
        • 複数のモデルで共通利用したい汎用的な処理を描く場合に適している。
      • 検証を追加するためのステップは下記の2つである。
        • ①検証用のメソッドをモデルクラスに登録する。
        • ②検証用のメソッドを実装する。
      • 検証のメソッドの基本的な仕事は『検証エラーを発見したら、errorsにエラー内容を格納する』である。
  • モデルの検証はモデルの登録や更新の時に自動的に内部で呼ばれ、検証エラーがあればデータベースへの登録・更新が行われないというのが基本の形である。
  • コールバック - 登録や削除などの重要なイベントの前後に任意の処理を挟むことができる仕組み。
コールバックの種類 代表的な使い道
before_validation 検証前の値の正規化
after_validation 検証結果(エラーメッセージ)の加工
before_save
before_create
before_update
saveのために裏側で行いたいデータ準備を行う。(ある属性の値に従ってある関連を作成するなど。)
検証エラーを出してもユーザにはどうすることもできない状態異常を防ぐために例外を出す。
after_save
after_create
after_update
そのモデルの状態に応じて他のモデルの状態に変えるなど、連動した挙動を実現する。
検証エラーを出してもユーザにはどうすることもできない状態異常を防ぐために例外を出す。
before_destroy 削除してOKかをチェックし、ダメなら例外を出すなどして防ぐ。
after_destroy そのモデルの削除に応じて他のモデルの状態を変えるなど連動した挙動を実現する。
  • トランザクション - 一連の複数の処理によるデータベースの生合成を保つための機能。
    • Railsではコールバック全体を1つのトランザクションで囲ってsaveを実行する。そのためコールバックの1つで例外が発生すると、ロールバックが発生し、以降のコールバックは実行されない。これによりコールバック全体での整合性が保たれる。
  • セッション - 1つのブラウザから連続して送られている一連のリクエストの間で『状態』を共有できるようにする仕組み。
    • Railsでは、コントローラからsessionというメソッドを呼び出すことで、セッションにアクセスできる。
    • sessionはハッシュのように扱うことができる。
    • セッションにデータを入れるには、任意のキーを指定して値を格納する。
  • Cookie - 複数のリクエストの間で共有したい『状態』をブラウザ側に保存する仕組み。
    • Cookie情報は、キーと値のペアの集合。
    • Railsでは、cookiesというメソッドでブラウザから受け取り、送り返すことになるCookie情報にアクセスし、データを取得したり設定したりすることができる。
    • Railsでは、セッションはCookieによってやり取りされるセッションIDをキーにしてしている。
    • Railsではセッションデータの保管場所を複数の選択肢から選ぶことができるが、デフォルトではこの保管場所もCookieとなっている。
    • ブラウザ側で対応するCookieデータを消せば、セッションはリセットされることになる。

「Chapter5 テストをはじめよう」

  • RSpec - Rubyにおける振舞駆動開発のためのテスティングフレームワーク。動く仕様書(Spec)として自動テストを書くという発想で作られており、要求仕様をドキュメントに記述するような感覚でテストケースを記述することができる。
  • Capybara - WebアプリケーションのE2E(End-to-End)テスト用フレームワーク
    • Rails5.1からRailsに同梱されるようになった。
    • MinitestやRSpecなどのテスティングライブラリと組み合わせて使う。
  • FactoryBot - テスト用データの作成をサポートするgem。FactoryBotを利用すると、テスト用のデータを簡単に用意し、テストから呼び出して利用することができる。
  • モデルのテスト
    • モデルのテストでは、検証やデータの制御、複雑なロジックの挙動などを個別のテストケースとして記述する。
    • 小さい粒度のテストが書けるため、システムテストなどでは行いづらい、様々な条件下でのわずかな挙動の違いを確認するのに特に向いている。
  • 結合テスト
    • モデルのテストとシステムの間を埋めるテスト。
    • モデルや単体テストでは確認しにくいものをテストする。
    • APIのテストに利用されることが多い。
  • その他のテスト
    • 機能テスト
      • 内部情報はリファクタリングの際などに変化しやすいため、テストのメンテナンス性という観点では注意が必要。
    • ビュー
      • ビューはユーザのニーズなどにより特に変化しやすいパーツなため、ビューのテストが多いと、メンテナンスが大変になりやすいという懸念がある。
    • ヘルパー
      • ビュー同様、よほど凝った処理をヘルパーで書いているため単体テストしたいというニーズでもなければ、利用したい場面はあまり多くない。

「Chapter6 Railsの全体像を理解する」

  • ルーティング - アクセスを受けて適切なアクションへと案内する仕組み。
    • 『どのようなURLへどのようなHTTPメソッドでアクセスされたら、どのコントローラのどのコントローラのどのアクションを呼び出したいか』をconfig/routes.rbに定義する。
    • 下記の2つの本質的に異なる構造間の連携を担っている。
      • URLやHTTPメソッドで表現するインターフェイスとしての構造
      • Rubyのプログラミング上の合理性で構造化したコントローラ・アクションの構造
  • ルーティングは、リクエストをアクションへと道案内する『ルート』の集合として捉えることができる。
  • 『ルート』を構成する5つの要素
要素の名前 要素の内容の例 説明
HTTPメソッド GET
POST
PATCH
PUT
DELETE
サーバへのリクエストの際に指定するもので、情報の送信・取得の方法を表す。
一般的なブラウザから送ることができるのはGETとPOSTのみだが、Railsでは_methodというリクエストパラメータの値に"PATCH","PUT","DELETE"という文字列が入ったPOSTリクエストを、それぞれPATCH,PUT,DELETEリクエストと解釈する。
URLパターン /tasks
/tasks/:id
URLそのものや、:idのように一部人にの文字が入るようなパターンを指定する。
URLパターンの名前 new_task
tasks
定義したURLパターンごとに一意な名前を付ける。この名前をもとに、対応するURLを生成するためのnew_task_path,new_task_urlといったヘルパーメソッドが用意される。
コントローラ tasks
(TasksController)
呼び出したいアクションのコントローラクラスを指定する。
アクション index 呼び出したいアクションを指定する。
  • routes.rbの定義がどのようになっているかは、rails routesコマンドで確認することができる。
  • RESTの設計原則
    • ①HTTPリクエストはそのリクエストで必要な情報を全て持ち、前のリクエストからの状態が保存されている必要がない。(ステートレス)
    • ②個々の情報(リソース)への『操作』の表現がHTTPメソッドとして統一されている。
    • ③個々の情報(リソース)がそれぞれ一意なURIで表されている。
    • ④ある情報(リソース)から別の情報を参照したいときは、リンクを利用する。
  • Railsでは、一覧・詳細・登録・更新・削除というよくある機能群を提供するために必要となるルート一式をresourcesメソッドを使って定義できる。
  • resourcesを使うと、アクションごとにgetメソッドやpostメソッドを使ってルートを定義する代わりに、一度で7つのアクションに対応する7つのルートを定義できる。
  • resourcesなどルートを定義する記述は、前提となるURL階層や、コントローラクラスを修飾するモジュール、コントローラクラス、URLパターン名のプリフィックスなどで構造化することができる。
  • 構造化のためのメソッド
    • scope - URL階層(:path)、モジュール(:module)、URLパターン名のプリフィックス(:as)などをオプションに指定することで、ブロックないの定義にまとめて一定の制約をかける。
    • namespace - URL階層、モジュール、URLパターン名に一括で一定の制約をかける。scopeと違い一括なため、URL階層だけに制約をかけるといったことはできない。
    • controller - コントローラを指定する。
  • 国際化 - 様々な国ごとに最適な表示などを行えるように基盤を整えること。
    • ①利用するロケールに対応する翻訳データのymlファイルをconfig/localesの下に配置する。
    • ②『現在のロケール』を示すI18n.localeが正しく設定された状態にする。
      • config/initializers/locale.rbなどの中で、デフォルト値であるconfig.i18n.default_localeを適切に設定する。
      • 複数の言語を切り替えて利用したい場合は、アプリケーションのフィルタなどで、リクエストごとにI18n.localeの値を変更する。
    • ③目的の翻訳データを利用する。基本的にI18n.localeに設定されたロケールの翻訳データを利用することができる。
      • I18n.tメソッド(I18n.translateメソッド)を呼ぶことで任意の翻訳データを利用することができる。
      • I18n.lメソッド(I18n.localizeメソッド)にDate系、Time系のオブジェクトを渡すと、ローカライズされた文字列表現を得ることができる。
      • モデルクラスやRailsのヘルパーメソッドが内部的に利用する翻訳データもある。
  • 翻訳ファイル - エラーメッセージやモデルのクラス名・属性名をja.ymlという翻訳ファイルに設定する。
    • 翻訳ファイルには下記のような設定ができる。
      • (ActiveRecordベースではない)ActiveModelベースのモデルの翻訳情報
      • localizeメソッドによって得られる日や日時の文字列表現
      • よくあるボタンのキャプションなど、Railsが内部的に利用する文字列
      • そのほか、任意の階層に任意のデータを定義できる
    • ymlファイルは、末尾に[ロケール名].ymlが付く任意の名前にすることができる。
    • config/locales以下のファイルは全て読めれるため、複数のファイルに分割して整理することができる。
  • タイムゾーンと共に日時を扱うには、Timeの代わりにActiveSupport::TimeWithZoneクラスを用いる。Railsが日時を扱う際(日時型のデータベースから読む時や、created_atなどのタイムスタンプを記録する時)には、自動的にこのクラスが利用される。
    • ActiveSupport::TimeWithZoneオブジェクトには下記の2点を設定することができる。
      • ①どのタイムゾーンの表現で日時データをDBに保存し、読み出し時にどう解釈するか
      • ②①に基づいて取り出した日時データを、どのタイムゾーンのTimeWithZoneオブジェクトとして生成するか。また、ユーザーの入力などに由来する日時データをモデルに代入する際、どのタイムゾーンの時刻であると解釈し、どのタイムゾーンのTimeWithZoneオブジェクトとして生成するか
  • Strong Parameters - コントローラでリクエストパラメータを受け取る際に、本当に安全なデータかどうかを検証した上で、取得するための仕組み。
  • アセットパイプライン - JavaScript, CSS, 画像などのリソース(アセット)を効率的に扱うための仕組み。処理内容として高級言語コンパイル、アセットの連結、アセットの最小化、ダイジェストの付与がある。
    • ブラウザにアセットを読み込ませる
      • Railsでは、CSSを読み込むにはstylesheet_link_tag、JavaScriptを読み込むにはjavascript_include_tagというヘルパーメソッドを使う。
      • CSSJavaScriptどちらも、第1引数に読み込みたいアセットファイル(拡張子は省略可能)を指定する。
      • 複数のファイルを列挙したり、オプションを指定したりすることもできる。
    • マニフェストファイル - アセットパイプラインの結合の機能を利用するために、具体的にどのソースコード同士を連結するかを決めて記述し、アセットパイプラインに伝えるファイル。
      • 新規にRailsアプリケーションを作成した時点で、JavaScriptCSSのそれぞれについて下記のファイルが生成される。
        • app/assets/javascripts/application.js
          • JavaScriptマニフェストファイルでは、『//=』で始まる行を、アセットパイプラインに指示を伝えるための特別な行として扱う。
          • require - 指定したJavaScriptファイルの内容を、記述した位置に取り込む。
          • require_tree - 指定されたディレクトリ配下の全ファイルの内容を結合し、記述した位置に取り込む。
        • app/assets/stylesheets/application.css
        • Sassの@importを利用して記述する。
      • マニフェストで指定するJavaScriptCSSのファイル名は、アセットの探索パスの設定をもとに引き当てられる。
    • production環境ではリクエストを高速に処理できるように、あらかじめアセットパイプラインを実行して静的ファイルを生成しておき、生成済みのファイルをリクエストの度に配信する。
    • プリコンパイル - 『あらかじめアセットパイプラインを実行して静的ファイルを生成する』という処理。
  • config/master.keyファイル(環境変数RAILS_MASTER_KEY』) - productionモードでアプリケーションを利用する場合に、Railsがproduction環境用の秘密情報を復号するために利用する鍵。
  • productionモードでサーバを起動するには下記のコマンドを使用する。
    bin/rails s --environment=production
  • credentials.yml.enc
    • production環境用の秘密情報(Credentails)を記述する。
    • 常に暗号化された状態で保存される。
    • 複合された内容を参照するには下記のコマンドを利用する。
      bin/ rails credentiald:show
    • 編集するには下記のコマンドを利用する。
      bin/rails credentials:edit

「Chapter7 機能を追加してみよう」

  • ransack - 検索機能の実装時に利用されるgem。
    • インストールすると、検索を行うためのransackメソッドがモデルに追加される。
    • ransackの提供するヘルパーsaerch_form_forを使って検索用のフォームを追加する。
    • ransackの提供するsort_linkヘルパーを用いることで、ソートが可能になる。
  • Action Mailer - Railsでメールを送るための仕組み。
    • メイラーはテンプレートを通じてメールを作成・送信する。
    • メイラーは下記のコマンドで作成できる。
      bin/rails g mailer メイラー名
    • deliver_nowは即時送信を行うためのメソッド。
    • mailcatcher - 送信されたメールをブラウザ上で確認できるようにしてくれるgem。
  • Active Storage - Rails5.2から同梱されたファイル管理gem。
    • クラウドストレージサービスへファイルをアップロードして、データベース上でActiveRecordモデルに紐付けることが簡単にできるようになった。
    • 下記のコマンドを実行することでインストールされ、マイグレーションファイルが作成される。その後作成されたマイグレーションファイルを下記のコマンドで反映させる。
      bin/rails active_storage:install
  • ページネーション - レコードの件数が一定数を超えた場合に複数のページに分割して表示を行うようにすること。
    • Railsでページネーションを実現するために利用されるgemにkaminariがある。

⚫︎難しく感じた部分

  • イメージしづらい部分があり全体的に難しいと感じた。
  • 上記の理由から特に初学者には難しいと思った。

⚫︎最後に

今回読んだ書籍は全体的に難しく、イメージしづらい部分があるように感じました。
まだまだ理解不足だということを痛感しました...。
しばらくはrails漬けになりそうです...。
これからアウトプットしたり経験を積んだりして慣れていきたいと思います!
気になった方は是非購入を検討してみてはいかがでしょうか。

Happiness Chainに入会して12ヶ月が経ちました。Euphoriaに加入して4ヶ月が経ちました。(3月月報)

皆様こんにちは、Amiaです。

私は「Happiness Chain」というオンラインのプログラミングスクールに入会して勉強しています。

そして「Happiness Chain」に入会してから12ヶ月が経ちました。
また、Euphoriaに加入して4ヶ月が経ちました。

それでは12ヶ月目に学習した内容を書いていきたいと思います。

⚫︎自己評価

自己評価は100点中20点です。
月全体の学習時間は前月よりも減ってしまいました。 色々と考えてしまうことがあり、あまり学習に集中できていない1ヶ月でした。
モチベーションやメンタルに左右されず、淡々と学習を行なっていけるようにしていきたいと思います。

⚫︎12ヶ月目の学習内容(約90時間)

Ruby on Rails

①動画でのインプット
②書籍でのインプット(途中)

⚫︎学習時間について

・1ヶ月目の学習内容(約66時間)
・2ヶ月目の学習内容(約88時間)
・3ヶ月目の学習内容(約88時間)
・4ヶ月目の学習内容(約74時間)
・5ヶ月目の学習内容(約83時間)
・6ヶ月目の学習内容(約82時間)
・7ヶ月目の学習内容(約70時間)
・8ヶ月目の学習内容(約73時間)
・9ヶ月目の学習内容(約56時間(12/21まで))
・10ヶ月目の学習内容(約98時間(1/31まで))
・11ヶ月目の学習内容(約98時間(2/29まで))
・12ヶ月目の学習内容(約90時間(3/31まで))
・Happiness Chain入会後累計学習時間(約1,023時間)

⚫︎成長したこと

・英語の学習を習慣化できたこと。

⚫︎良かったこと

・毎日少しの時間でも学習を継続できたこと。

⚫︎悪かったこと

・メンタルが不安定だったこと。
・学習にあまり集中できていなかったこと。

⚫︎改善すること(ネクストアクション)

・メンタルのケアを行う。
・イベントや雑談会に参加する。
・隙間時間を有効的に使う。

⚫︎感想・来週の目標

・1日の学習時間を伸ばす。
・コミュニケーション能力向上のために必要なタスクをこなす。

⚫︎1ヶ月振り返ってみての感想

今月はRailsのインプットのみで終わってしまいました。
環境構築等でエラーが頻繁に発生したため、想定していたよりも時間が掛かっています。
焦ることはあまり良くないのですが、なかなか難しいですね...。

それではまた遅くて1ヶ月後ぐらいにお会いしましょう...。

Happiness Chainに入会して11ヶ月が経ちました。Euphoriaに加入して3ヶ月が経ちました。(2月月報)

皆様こんにちは、Amiaです。

私は「Happiness Chain」というオンラインのプログラミングスクールに入会して勉強しています。

そして「Happiness Chain」に入会してから11ヶ月が経ちました。
また、Euphoriaに加入して3ヶ月が経ちました。

それでは11ヶ月目に学習した内容を書いていきたいと思います。

⚫︎自己評価

自己評価は100点中30点です。
月全体の学習時間は前月と変わりませんでした。 月の前半はあまり学習時間を確保できませんでしたが、月の後半ぐらいから1日の学習時間を伸ばすことができたおかげで学習時間を減らさずに継続できたので良かったです。 この調子で来月も進み続けていけるようにしたいと思います。

⚫︎11ヶ月目の学習内容(約98時間)

SQL

①書籍でのインプット
②書籍でのインプット
③アウトプット課題

・REST

①動画でのインプット
②アウトプット課題

Ruby on Rails

①動画でのインプット(途中)

⚫︎学習時間について

・1ヶ月目の学習内容(約66時間)
・2ヶ月目の学習内容(約88時間)
・3ヶ月目の学習内容(約88時間)
・4ヶ月目の学習内容(約74時間)
・5ヶ月目の学習内容(約83時間)
・6ヶ月目の学習内容(約82時間)
・7ヶ月目の学習内容(約70時間)
・8ヶ月目の学習内容(約73時間)
・9ヶ月目の学習内容(約56時間(12/21まで))
・10ヶ月目の学習内容(約98時間(1/31まで))
・11ヶ月目の学習内容(約98時間(2/29まで))
・Happiness Chain入会後累計学習時間(約931時間)

⚫︎成長したこと

・アウトプット課題を通して、SQLについて少しずつ理解が深まったこと。
・学習に対する心構えが変わったこと。

まだまだ知識不足ですので、これからも日々積み重ねていきたいです。

⚫︎良かったこと

・毎日少しの時間でも学習を継続できたこと。
・月の後半から学習時間を伸ばすことができたこと。
・隙間時間を前月に比べて有効に使えたこと。

⚫︎悪かったこと

・環境の変化等で月の前半は学習をあまり行えていなかったこと。
・英語の学習が疎かになってしまったこと。
・月末に体調を崩してしまいスクール内のイベントに参加できなかったこと。

⚫︎改善すること(ネクストアクション)

・イベントや雑談会に参加する。
・隙間時間を有効的に使う。

⚫︎感想・来週の目標

・英語の学習を習慣化する。
・1日の学習時間を伸ばす。
・コミュニケーション能力向上のために必要なタスクをこなす。

⚫︎1ヶ月振り返ってみての感想

今月は環境の変化もあり、生活リズムを崩してしまうことがありました。ですが、そんな中毎日少しでも学習を行うことができたことは良かったと思います。
思いの外、SQLのインプットに時間が掛かってしまいましたがなんとか課題まで完了することができました。
SQLについては繰り返しやっていくことで慣れていくしかないのかな、と思います。 まだまだ知識不足なため所々復習を挟みつつ、学習を進めていきたいと思います。

疎かになっていた英語の学習についても来月からは習慣化していきたいと思います。

それではまた遅くて1ヶ月後ぐらいにお会いしましょう🖐️

『REST API』について少し理解を深めました。

皆様こんにちは、Amiaです。

私はここ何日かで「REST API」について少しインプットしました。
そのため今回はアウトプットも兼ねて「REST API」について記事を書いていきたいと思います。

よろしければ最後までご覧になっていただければと思います。

⚫︎REST APIとは

  • REST(Representational State Transfer)の設計原則に従うAPIのこと。

⚫︎RESTfulとは

  • RESTで求められる原則に従っていること。

⚫︎CRUDに相当するメソッド

操作 意味 メソッド
Create 作成
(リソース名が未定の場合に使用する。)
POST
Create 作成
(リソース名が決まっている場合に使用する。)
PUT
Read 読み取り GET
Update 更新 PUT
Delete 削除 DELETE

⚫︎URI設計で考慮すること

  • 短く入力しやすいこと。
  • 人間が読んで理解できること。
  • 大文字小文字が混在していないこと。
  • 単語はハイフンでつなげる。
    →ハイフンで単語を連結するよりもURIを根本的に見直したほうが良い。
  • 単語は複数形を利用すること。
  • エンコードを必要とする文字を使わないこと。
  • サーバー側のアーキテクチャを反映しないこと。
  • 改造しやすいこと。
  • ルールが統一されていること。

⚫︎HTTPメソッドとURI

  • URIはリソースを示す。
  • HTTPメソッドはリソースに対する操作を示す。

今回は例としてmovieをリソースとしてCRUD操作のHTTPメソッド、URIを定義してみます。

操作 URI HTTP method
映画の一覧を取得 http://api.example.com/movies GET
映画の新規登録 http://api.example.com/movies POST
特定の映画の取得 http://api.example.com/movies/678 GET
特定の映画の更新 http://api.example.com/movies/678 PUT
特定の映画の削除 http://api.example.com/movies/678 DELETE

⚫︎リソースを特定するパラメータ

  • 絞り込みの方法には2種類ある。
種類 概要 使用用途
クエリパラメータ URLの末尾にある「?」に続くキーバリュー。
GET http://api.example.com/users?page=3
一意なリソースを表示したいときに利用する。
パスパラメータ URL中に埋め込まれるパラメータ。
GET http://api.example.com/users/123
特定のものに条件を加える場合に利用する。

⚫︎REST API設計レベル

設計レベルは4段階存在する。

⚪︎LEVEL0 : HTTPを使っている。

REST APIの基本レベル。RPCスタイルのXML通信。
* HTTPは単なる通信手段として利用。
* 1URLで全て完結。
* リクエストボディーに処理と引数が含まれる。

⚪︎LEVEL1 : リソースの概念を導入。

リソースごとにURLを分割。
* リソースごとにURLを分離。
* HTTPメソッドは活用できていないため、GETかPOSTのみで通信。

⚪︎LEVEL2 : HTTPの動詞を導入。

LEVEL1に加えてHTTPメソッドを活用。
* リソースに対してHTTPメソッドを使ったCRUD操作が行われている。

⚪︎LEVEL3 : HATEOASの概念の導入。

LEVEL2に加えてレスポンスにリソース間のつながりが含まれる。
* レスポンスに現在の状態に関連するハイパーリンクが含まれている。
(=HATEOASに相当する情報がレスポンスに含まれている。)

⚫︎最後に

今回はこの辺りで終わりたいと思います。
それではまた🖐️

『達人に学ぶDB設計 徹底指南書』を読みました。

皆様こんにちは、Amiaです。

私はここ何週間かでタイトルにもある通り『達人に学ぶDB設計 徹底指南書』を読んでいました。
そのため今回は上記の書籍について読んだ感想等をまとめいきたいと思います。

よろしければ最後までご覧になっていただければと思います。

⚫︎良かった点

  • 論理設計だけでなく物理設計についても記載されている。
  • バッドノウハウ、グレーノウハウの例が豊富に記載されていて、著者の実体験にも基づいておりイメージしやすい。

⚫︎学んだこと

「第1章 データベースを制する者はシステムを制す」

  • DOA:システムを作る際にプログラムよりも前にデータの設計から始める方法論。
  • 3層スキーマ
    • 外部スキーマ
      • システムの利用者であるユーザーから見て、データベースがどのような機能とインタフェースを持っているかを定義するスキーマ
      • テーブルやビュー。
    • 概念スキーマ
      • データベースに保持するデータの要素及び、データ同士の関係を記述するスキーマ
      • テーブル定義。
    • 内部スキーマ
      • 概念スキーマで定義された論理データモデルを、具体的にどのようにDBMS内部に格納するかを定義するスキーマ
      • データの物理的配置。
    • 概念スキーマは何のためにあるか?
      • 外部スキーマと内部スキーマの間に位置することで、両者の変更が互いに影響し合わないようにするための緩衝材の役割を果たしている。

「第2章 論理設計と物理設計」

  • 論理設計:概念スキーマを定義する設計のこと。
  • システムの世界での「論理」:「物理層の制約にとらわれない」という意味。
  • システム開発におけるデータベース設計は下記の手順で行われる。
  • 論理設計の四つのタスク
    • ①エンティティの抽出
      • システムのためにどのようなデータが必要になるかを抽出する。
      • このタスクの一部は「要件定義」と重なっている。
    • ②エンティティの定義
      • 各エンティティがどのようなデータを保持するかを決める。
    • ③正規化
      • エンティティについて、システムでの利用がスムーズに行えるように整理する。
    • ④ER図の作成
      • エンティティ同士の関係を表現する図を作成する。
  • 物理設計の五つのタスク
    • ①テーブル定義
      • 論理設計で定義された概念スキーマをもとに、それをDBMS内部に格納するための「テーブル」の単位に変換していく作業。
    • ②インデックス定義
    • ③ハードウェアのサイジング
      • システムで利用するデータサイズを見積り、それに十分な容量の記憶装置を選定する。
      • システムが十分な性能を発揮できるだけのスペックのCPUやメモリを持ったサーバーを選定する。
    • ④ストレージの冗長構成決定
      • どの程度冗長化して信頼性(可用性)・性能を確保するかでRAIDのレベルを決める。
    • ⑤ファイルの物理配置決定
      • データベースのファイルをどのディスク(またはRAIDグループ)に配置するかを考える。
      • DBMSでは自動化が進んでいるが、基本的な考え方を押さえておくことが重要。
      • データベースに格納されるファイルは下記の5種類に大別される。このうち開発者が意識するのは❶と❷だけ。
      • ❶データファイル
        • ユーザーがデータベースに格納するデータを保持するためのファイル。
      • ❷インデックスファイル
        • データに作成されたインデックスが格納されるファイル。
      • ❸システムファイル
        • DBMSの内部管理用に使われるデータを格納する。
      • ❹一時ファイル
        • DBMS内部での一時的なデータを格納するために使われる。
      • ❺ログファイル
        • DBMSによって呼び方が異なる。
        • DBMSは、テーブルのデータに対する変更を受け付けた場合、即座にデータファイルを更新しているわけではない。一旦、このログファイルに変更分を溜め込んだ後に、一括してデータファイルに変更を反映している。
  • データベースにおいては、データの整合性とパフォーマンスの間に強いトレードオフが存在する。
  • 三つのバックアップ方式
    • フルバックアップ(完全バックアップ)
      • ある時点でそのシステムで保持されている全てのデータをバックアップする方式。
    • 差分バックアップ
      • 前回のフルバックアップ後に変更された部分のデータだけをバックアップする方式。
    • 増分バックアップ
      • 前回のフルバックアップ後にその日に変更された部分のデータだけをバックアップする方式。
  • バックアップ方式にもトレードオフがある。
  • リストア及びリカバリの手順

「第3章 論理設計と正規化 ~ なぜテーブルは分割する必要があるのか?」

  • 正規化
    • 正規化とは更新時の不都合/不整合を排除するために行う。
    • 正規化は従属性を見抜くことで可能になる。
    • 正規形はいつでも非正規形に戻せる。
    • 正規化は常にするべきか?
      • 第3正規形までは原則として行う。
      • 関連エンティティが存在する場合は関連とエンティティが1対1に対応するように注意する。
  • 正規形:データベースで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式
  • 第1正規形
    • 1つのセルの中には1つの値しか含まない状態にする。
  • 第2正規形
    • テーブル内で部分関数従属を解消し、完全関数従属のみのテーブルを作る。
  • 第3正規形
    • テーブル内での推移的関数従属を解消する。
  • ボイス-コッド正規形
    • 非キーからキーへの関数従属をなくす。
  • 第4正規形
    • 独立な多値従属性が複数存在するテーブルを分割することで作られる。
  • 第5正規形
    • 関連がある場合は、それに対応する関連エティティを作る。

「第4章 ER図 ~ 複数のテーブルの関係を表現する」

  • IDEF1X
    • 角の尖った四角で表記したエンティティ
      • 独立エンティティ:他のテーブルのデータに依存することなく、データを保持することのできるエンティティ。
    • 角の丸い四角で表記したエンティティ
      • 従属エンティティ:他のテーブルにデータが存在しなければ、データを保持することのできないエンティティ。
    • エンティティ間の関連:カーディナリティの「多」が黒丸(⚫︎)で表現される。

「第5章 論理設計とパフォーマンス ~ 正規化の欠点と非正規化」

  • 正規化と検索SQLのパフォーマンスは強いトレードオフの関係にある。
  • 非正規化は最後の手段。
  • 正規化の次数は高ければ高いほど良い。
  • 冗長性排除によって引き起こされる性能問題
    • サマリデータの冗長性排除
      • サマリデータを冗長に保持すると正規形に違反するが、検索を高速化できる。
    • 選択条件の冗長性排除
      • 選択条件を冗長にすると第2正規形ではなくなる。
      • 選択条件を冗長に保持すると正規形に違反するが、検索を高速化できる。
  • 非正規化のリスク
    • ①非正規化は検索のパフォーマンスは向上させるが、更新のパフォーマンスを低下させる。
    • ②データのリアルタイム性(鮮度)を低下させる。
    • ③後続の工程で設計変更すると手戻りが大きい。
  • 論理設計には物理設計の知識が必要である。

「第6章 データベースとパフォーマンス」

  • インデックス設計:SQLのパフォーマンス改善のための非常にポピュラーな手段。
    • アプリケーション透過的
      • インデックスを使うかどうかはDBMSが自動的に判断するため、アプリケーションのコードに影響を与えない。
    • データ透過的
      • テーブルに格納されているデータの中身が影響を受けることはない。
      • テーブルの構造が変化することはない。
    • 大きな性能改善効果
    • B-treeインデックス:最も頻繁に利用するインデックス。
      • B-treeインデックスの長所:親ソート性、均一性、持続性、処理汎用性、非等値性が平均的に優れている。
      • B-treeインデックスの設計指針
        • ①大規模なテーブルに対して作成する。
          • データ量が少ない場合はインデックスの効果はない。
        • ②カーディナリティの高い列に作成する。
          • カーディナリティが高い列ほどインデックスの効果が高い。ただし、値が平均的に分散しているほうが良い。
            SQL文でWHERE句の選択条件、または結合条件に使用されている列に作成する。
      • B-treeインデックスを利用できていないSQL
        • インデックス列に演算を行なっている。
        • 索引列に対してSQL関数を適用している。
        • IS NULL述語を使っている。
        • 否定形(<>)を用いている。
        • ORを用いている。
        • 後方一致、または中間一致のLIKE述語を用いている。
        • 暗黙の型変換を行なっている。
    • B-treeインデックスの注意事項
      • 主キー及び一位制約の列には作成不要。
      • B-treeインデックスは更新性能を劣化させる。
      • 定期的なメンテナンスを行うことが望ましい。
  • 統計情報
    • テーブルやインデックス等「データ」についてのデータ。(メタデータ)
    • DBMSは上記のメタデータを頼りにSQLのアクセスパスを決定する。
    • SQL文によってテーブルにアクセスする流れ
      • ①ユーザーからSQL文がDBMSへ発行される。
      • DBMS内の「パーサ」で構文チェックを行い、「オプティマイザ」というモジュールへ送る。
      • オプティマイザは「カタログマネージャ」というモジュールに、統計情報の照会をかける。
      • オプティマイザが統計情報から最短経路を選択してSQLを手続きに変換する。その後、テーブルへアクセスを行う。
    • 統計情報の収集タイミング
      • データが更新された後、なるべく早く。
      • 統計情報収集は原則、夜間帯に実施する。

「第7章 論理設計のバッドノウハウ

  • バッドノウハウ(アンチパターン)のダメな点
    • ①システムの品質に左右する。
    • ②後から変更することが容易ではない。
  • 論理設計の代表的なバッドノウハウ
    • 非スカラ値
      • 1つのセル内で複数の値を持つことができるデータ型や構造。
      • かつては標準機能で「配列型」があり、非スカラ値を含むテーブルを作ることができた。
      • 情報は可能な限り分割して保存するのが良いが、意味を壊してはいけない。
    • ダブルミーニング
      • 同一の列だが、途中から格納するデータが変わっている。(同一の列が2つの意味を持つ。)
      • テーブルや列の意味は、一度決めたら容易に変更してはならない。
    • 単一参照テーブル
      • あらゆるタイプのマスタテーブルを1つにまとめる。
      • 利点
        • マスタテーブルの数が減るため、ER図やスキーマがシンプルになる。
        • コード検索のSQLを共通化できる。
      • 欠点
        • 大きめの可変長文字列型で宣言する必要がある。
        • レコード数が多くなり、検索のパフォーマンスが悪化する。
        • コードタイプやコード値を間違えて指定してもエラーになることがないため、バグに気づきにくい。
        • ER図の可読性を下げる。
      • テーブルにポリモフィズムはいらない。
    • テーブル分割
      • 水平分割:レコード単位でテーブルを分割する手段。
        • テーブルを分割することでパフォーマンスを改善できる。
        • 分割する意味的な理由がない。
        • 拡張性に乏しい。
        • 他の代替手段がある。
      • 垂直分割:列単位でテーブルを分割する手段。
        • SQL文のパフォーマンス改善が可能。
        • 分割する意味的な理由がない。
        • 「集約」で代替可能。
      • 集約:テーブル分割の代替案に位置づけられる方法。下記の2種類に分類される。
        • 列の絞り込み
          • 元のテーブルから必要な列だけを持った新しいテーブルを追加作成する。
          • 定期的に元のテーブルとの同期が必要。
        • サマリテーブル
          • 集約関数によってレコードを集約した状態で保持する。
          • 事前に集約を行ったテーブルを作っておく。
          • 更新のタイムラグによってデータの整合性がとれない時間帯が生じるデータ同期の問題は列の絞り込みと同じ。
    • 不適切なキー
      • 主キー、外部キー、結合キーについては
        • 可変長文字列は不変性がないため不向き。
        • 同じデータを意味するキーは同じデータ型にする。
        • キーには固定長文字列の「コード」列が望ましい。
    • ダブルマスタ:同じ役割を果たすはずのマスタテーブルが2つ存在するようなケース。
      • SQLを複雑にして、パフォーマンスを悪化させる。
      • システム統廃合によって生じることが多い。
  • バッドノウハウのどこが悪いか?
    • 運用にかかるコストが高くなる。
    • エンジニアやプログラマの設計に対する理解を妨げる。
    • 設計変更が難しい。

「第8章 論理設計のグレーノウハウ」

  • グレーノウハウ:バッドノウハウとははっきり断定することができないが、無神経に使うと開発や運用に支障をきたすような設計のこと。
    • 代理キー
      • 下記のような主キーが決められない、または主キーとして不十分ケースに利用される。
        • そもそも入力データに主キーにできるような一意キーが存在しない。
        • 一意キーはあるが、サイクリックに使いまわされる。
        • 一意キーはあるが、途中で指す対象が変化する。
      • 極力代理キーの使用は避けて、自然キーによる解決を図るべきである。
        • 代理キーがそもそも論理的に不要なキーのため。
        • 論理モデルをわかりにくくしてしまうため。
      • 代理キーを使わず、自然キーだけで解決する場合
        • そもそも入力データに主キーにできるような一意キーが存在しない。
          • データベース側で打つてはない。
            • 業務使用を調整する。
            • データベースに投入される前のアプリケーションでデータが一意になるように整形する。
        • 一意キーはあるが、サイクリックに使いまわされるか途中で指す対象が変化する。
          • 時点や期間を表す列を持つ。
    • 列持ちテーブル
      • 利点
        • シンプルな設計。
        • 入出力のフォーマットと合わせやすい。
      • 欠点
        • 列の増減が難しい。
        • 無用のNULLを使わなくてはならない。
      • 特殊な状況でない限り、原則として列持ちテーブルは使うべきではない。基本的には「行持ち」テーブル構成を採用するべき。
      • 行持ち⇔列持ち間のデータ移行はSQLで簡単に変更できる。
    • アドホックな集計キー:都道府県テーブルに対してつける地方コード列等のような場当たり的につけるキーのこと。
      • テーブルに場当たり的にキーを追加していくとパフォーマンスを劣化させる。
      • 解決策
        • キーを別テーブルに分離する。
          • SQLでは統合処理が必要になるため、パフォーマンス問題の解決にはならない。
        • ビューを使う。
        • GROUP BY句の中でアドホックキーを「アドホック」に作る。
          • CASE式で割り振る。
    • 多段ビュー
    • ビューは物理的にはSELECT文が書かれたファイルにすぎない。
    • ビュー定義のSELECT文を実行して、オリジナルのテーブルにアクセスしてデータを取り出している。
    • ビューの背後にあるテーブルの存在を常に意識する。
    • データクレンジング:業務で利用されていたデータをデータベースに登録できる状態にすること。
      • データクレンジングはデータベース設計に先立って行う必要がある。
      • 代表的なデータクレンジングの内容
        • 一意キーの特定
          • 一意キーの存在しないデータは、バッドノウハウ「不適切なキー」をも生み出す。
        • 名寄せ:人名や企業名の表記揺れを解消して名称を統一する。

「第9章 一歩進んだ論理設計 ~ SQL木構造を扱う」

  • リレーショナルデータベースで木構造を扱う方法
    • 隣接リストモデル
      • 最も古くから知られている方法。
      • ノードのレコードに親レコードの情報(ポインタ)も持たせようとするもの。
      • 更新や検索のクエリが極めて複雑になり、パフォーマンスも悪いという欠点がある。
    • 入れ子集合モデル
      • ノードを点ではなく面積を持った「円」としてとらえる。
      • ノード間の階層関係を縁の包含関係によって表す。
      • 更新対象以外のレコードも連動して更新しなければいけいないため、更新時のパフォーマンスが悪い。
    • 経路列挙モデル
      • ノードをディレクトリ(フォルダ)と見なし、各ノードまでの経路(path)を記述する。
      • 検索が簡単で更新が複雑。

⚫︎難しく感じた部分

  • イメージしづらい部分があり全体的に難しいと感じた。
  • 第6章は内部的な内容で特に難しいと感じた。

⚫︎最後に

今回読んだ書籍は全体的に難しく、イメージしづらい部分が多くあるように感じました。
まだまだ理解不足だということを痛感しました...。
これからアウトプットしたり経験を積んだりして慣れていきたいと思います。
気になった方は是非購入を検討してみてはいかがでしょうか。

『スッキリわかるSQL入門』を読みました。

皆様こんにちは、Amiaです。

私はここ何週間かでタイトルにもある通り『スッキリわかるSQL入門』を読んでいました。
そのため今回は上記の書籍について読んだ感想等をまとめいきたいと思います。

よろしければ最後までご覧になっていただければと思います。

⚫︎良かった点

  • イラストや図が多く使用されている。
  • 巻末に256問という多くの問題が掲載されているため、インプット後の復讐になる。

⚫︎学んだこと

「第2章 基本文法と4第命令」

  • SQL文の末尾にセミコロンを付けることで文の終了を表す。
  • 予約語は大文字と小文字のどちらで記述してもよい。
  • シングルクォートで括らずに記述されたリテラルは数値として扱われる。
  • シングルクォートで括られたリテラルは基本的に文字列として扱われる。
  • シングルクォートで括られて、'2022-02-25'のような一定の形式で記述されたリテラルは日付として扱われる。

「第3章 操作する行の絞り込み」

  • WHERE句に記述できるものは、結果が必ず真(TRUE)または偽(FALSE)となる条件式のみ。
    →1行ずつ順番に条件に合うかどうかチェックするため。
  • NULL=<>では判定できない。必ずIS NULLIS NOT NULLを使用して条件式を作る。
  • パターン文字列の中で、単なる文字として%_を使いたい場合は、下記のようにESCAPE句を併用した記述を行う。
    SELECT * FROM 家計簿 WHERE メモ LIKE '%100$%' ESCAPE '$'
  • IN演算子:括弧内に列挙した複数の値(値リスト)のいずれかにデータが合致するかを判定する演算子
SELECT * FROM 家計簿 WHERE 費目 IN('食費',  ' 交通費')
  • NOT IN演算子:括弧内に列挙した値のどれとも合致しないことを判定する。<> ALLと同じ。
SELECT * FROM 家計簿 WHERE 費目 NOT IN('食費', '交通費')
  • ANY演算子:括弧内に列挙した値リストのそれぞれと比較して、いずれかが真なら全て真。INと同じ。
式 基本比較演算子 ANY(値1, 値2, 値3...)
  • ALL演算子:括弧内に列挙した値リストのそれぞれと比較して全て真なら真。
式 基本比較演算子 ALL(値1, 値2, 値3...)
  • 主キーとなる列が持つべき特性
    • 必ず何らかのデータが格納される。(NULLではない。)
    • 他の行と値が重複しない。
    • 一度決めた値は変化しない。

「第4章 検索結果の加工」

  • ORDER BY句を付けないSELECT文では、結果表の各行の並び順は実質的に「ランダム」である。
  • OFFSET-FETCH句:OFFSET句には先頭から除外したい行数を記述する。除外せずに1件目から取得したい場合には0を指定する。FETCH句には取得したい行数を指定する。FETCH句を省略すると該当するすべての行が抽出される。
SELECT 費目, 出金額 FROM 家計簿 ORDER BY 出金額 DESC
OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY
  • UNION演算子:2つのSELECT文をUNIONで繋いで記述すると、それぞれの検索結果を足し合わせた和集合の結果が返される。
  • EXCEPT演算子:あるSELECT文の検索結果に存在する行から別のSELECT文の検索結果に存在する行を差し引いたさ集合を返す。
  • INTERSECT演算子:2つのSELECT文に共通する行を集めた積集合を返す。

「第5章 式と関数」

  • DBMSによる処理の原則
    • DBMSは、テーブル内の各行を1つずつ順番に処理していく。
    • 式の評価等も各行で行われる。
  • 文字列 || 文字列で文字列同士を連結できる。
  • CASE演算子:列の値や条件式を評価し、その結果に応じて値を自由に変換する。
SELECT 費目, 出金額,
              CASE 費目 WHEN '居住費' THEN '固定費'
                                 WHEN '水道光熱費' THEN '固定費'
                                 ELSE '変動費'
              END AS 出費の分類
FROM 家計簿 WHERE 出金額 > 0
  • 関数はDBMS製品によって構文や機能が大きく異なるため、詳細は製品マニュアルを参照する必要がある。
  • TRIM関数:ある文字列の前後についている余計な空白を除去する。類似する機能を持つ関数として下記のものがある。
  • LTRIM関数:左側の空白を除去した文字列を返す。
  • RTRIM関数:右側の空白を除去した文字列を返す。
    • REPLACE関数:文字列の一部を別の文字列に置換する関数。
    • SUBSTRING関数 / SUBSTR関数:文字列の一部分を取り出す。どちらを利用できるかはDBMS製品によって異なる。
  • CONCAT関数:文字列を連結する。
  • ROUND関数:指定した位置で四捨五入した結果を返す。有効とする桁数に指定する値が正の場合は少数部の桁数、負の場合は整数部の桁数を表す。
  • TRUNC関数:指定桁で切り捨てる。有効とする桁数に指定する値が正の場合は少数部の桁数、負の場合は整数部の桁数を表す。
  • POWER関数:ある値のべき乗を計算する。

  • 現在の日時を得る関数は下記のようなものがある。

    • CURRENT_TIMESTAMP関数:現在の日時(年、月、日、時、分、秒)を得る。
    • CURRENT_DATE関数:現在の日付(年、月、日)を得る。
    • CURRENT_TIME関数:現在の時刻(時、分、秒)を得る。
  • CAST関数:データ型を変換する。

  • COALESCE関数:受け取った引数を左から順番にチェックして、その中から最初に見つかったNULLでない引数を返す。また下記のように記述することで「NULLの場合の代替値を明示的に表示する」ことができる。
SELECT 日付, 費目,
               COALESCE(メモ, '(メモはNULLです)') AS メモ,
               入金額, 出金額
FROM 家計簿

「第6章 集計とグループ化」

  • 集計関数の結果は必ず1行になる。
  • COUNT(*)COUNT(列)の違い。
    • COUNT(*)は、単純に行数をカウントする。(NULLの行も含める。)
    • COUNT(列)は、指定列がNULLである行を無視してカウントする。
  • 集計関数はSELECT文の選択列リストかORDER BY句、HAVING句だけに記述できる。
  • SQLの結果表について
    • 結果表は必ず長方形型になる。
    • 結果表が凸凹になるようなSQL文は実行できない。
  • GROUP BY句に複数の列をカンマで区切って指定すれば、複数の列を基準にしたグループ化をすることもできる。
  • 集計関数はWHERE句に記述できない。
    →行を絞り込む段階ではまだ集計が終わっていないため。
  • HAVING句:集計処理を行った後の結果表に対して絞り込みを行いたい場合に使用する。
  • SELECT文の基本構文
SELECT 選択列リスト
FROM テーブル名
[WHERE 条件式]
[GROUP BY グループ化列名]
[HAVING 集計結果に対する条件式]
[ORDER BY 並び替え列名]
  • グループ集計を行うSELECT文の選択列リストに指定する列は、下記のどちらかに当てはまるものでなければならない。
    ①GROUP BY句にグループ化の基準列として指定されている。
    ②集計関数による集計の対象となっている。

「第7章 副問い合わせ」

  • 副問い合わせの3つのパターン
    ①単一行副問い合わせ:副問い合わせの検索結果が1行1列の値になるパターン。
    ②複数行副問い合わせ:副問い合わせの検索結果が複数の行から成る単一列(n行1列)の値になるパターン。
    ③表形式の結果となる副問い合わせ:副問い合わせの検索結果が複数の行と複数の列から成る表形式(n行m列)の値となるパターン。
  • 相関副問い合わせ
    • 主問い合わせがテーブルから行を絞り込む過程で各行について抽出の可否を判断するために、繰り返し副問合せを実行する。
    • 上記の挙動を行うことから、DBMSの負荷は大幅に増加する。

「第8章 複数テーブルの結合」

  • 左外部結合(LEFT JOIN):NULLの行を生み出してでも、左表の全行を必ず出力する。
  • 右外部結合(RIGHT JOIN):NULLの行を生み出してでも、右表の全行を必ず出力する。
  • 完全外部結合(FULL JOIN):NULLの行を生み出してでも、左右の表の全行を必ず出力する。
  • 外部結合:本来結果表から消滅してしまう行も強制的に出力する結合。
  • 内部結合:結合すべき相手の行が見つからない場合に行が消滅してしまう結合。
  • FULL JOINを利用できないDBMSでは、UNIONを使用して同等の処理を実現できる。
SELECT 選択列リスト FROM 左表の名前
LEFT JOIN 右表の名前
ON 左表の結行条件列 = 右表の結合条件列
UNION
SELECT 選択列リスト FROM 左表の名前
RIGHT JOIN 右表の名前
ON 左表の結合条件列 = 右表の結合条件列
  • 非統合結合
    • 結合の条件には=以外の演算子を用いた条件式も記述することができる。
    • 動作の仕組みは通常の結合と同じだがDBMSにかかる負荷は大きなものとなる。

「第9章 トランザクション

  • DBMSに対して複数の利用者が同時に処理を要求することで発生する副作用には下記の3つが知られている。
    ①ダーティーリード:まだコミットされていない未確定の変更を他の人が読めてしまう副作用。
    ②反復不能読み取り:あるテーブルに対してSELECT文を実行した後、他の人がUPDATE文でデータを書き終えると次にSELECTした際に検索結果が異なってしまう副作用。
    ③ファントムリード:2回のSELECT文の間に他の人がINSERT文で行を追加すると、最初と次のSELECTで取得する結果の行数が変わってしまう副作用。
  • 上記の副作用は各トランザクションを分離することで防ぐことができる。
  • SQL文を使って指定した対象を明示的にロックすることができる。
  • ロックをかける際には制限の強さを指定することができる。
    • 排他ロック:他からのロックを一切許可しないため主にデータの更新時に利用される。
    • 共有ロック:他からの共有ロックを許す特性があるためデータの読み取り時に多く利用される。
  • 通常、SELECT文で選択した行には自動的に共有ロックがかかる。
  • NOWAITオプションを指定した場合にはDBMSはロックの解除を待機せずにすぐさまロック失敗のエラーを返すため、トランザクションは即時終了する。
  • 表全体をロックすることも可能。
  • ロックは最小限にすること!
    • 明示的にロックする時は、必要最小限の範囲に留める。
    • 排他ロックの代わりに共有ロックを使用できないかを検討する。
  • デッドロック:データベースで同時にたくさんのトランザクションが実行されると稀に陥る状態。トランザクションの処理が途中で永久に止まってしまう。
  • デッドロックを予防する方法
    トランザクションの時間を短くする。
    ②同じ順番でロックするようにする。

「第10章 テーブルの作成」

  • 予期しない値を格納できないように制限をかけることで、人為的ミスによるデータ破壊の可能性を減らすことができる。
  • 制約はCREATE TABLE文でテーブルを定義する際に、列定義の後ろに指定することが可能。
    ①NOT NULL制約:設定された列には、NULLの格納は許可されない。NOT NULL制約はDEFAULT指定と組み合わせて利用されることがほとんど。
    ②UNIQUE制約:ある列の内容が決して重複してはならない場合に付ける。
    ③CHECK制約:ある列に格納される値が妥当であるかを細かく判定したい場合に付ける。「CHECK」の後ろに括弧内に記述した条件式が真となるような値だけが格納を許される。
    *主キー制約:主キーの役割を担う列に付ける。この制約が付いている列は「NULLも重複も許されない列」ではなく、そのテーブルで管理しているデータを一意に識別する。主キー制約を付ける方法は下記の2つがある。
①主キー制約の指定(単独列)
CREATE TABLE 費目(
     ID INTEGER              PRIMARY KEY,
     名前 VARCHAR(40) UNIQUE
)

②主キー制約の指定(複合主キー)
CREATE TABLE 費目(
     ID INTEGER,
     名前 VARCHAR(40) UNIQUE,
     PRIMARY KEY(ID, 名前)
)
  • 外部キー制約:参照整合性が崩れるようなデータ操作をしようとした場合にエラーを発生させて、強制的に処理を中断させる制約。CREATE TABLE文で外部キー制約をかけるには、下記のように指定する。
外部キー制約の指定方法①
CREATE TABLE テーブル名(
     列名 型 REFERENCES 参照先テーブル名(参照先列名)
     :
)

外部キー制約の指定方法②
CREATE TABLE テーブル名(
     :
     FOREIGN KEY(参照元列名)
       REFERENCES 参照先テーブル名(参照先列名)
)

「第11章 さまざまな支援機能」

  • ある列についてインデックスを作成すると、その列に関する検索が高速化する。
  • インデックス設定の効果が得られやすい列
    • WHERE句に頻繁に登場する列
      • 完全一致検索や前方一致検索ではインデックスを利用した高速な検索が行われることがある。
      • 部分一致検索や後方一致検索ではインデックスは利用されない。
    • ORDER BY句に頻繁に登場する列
    • JOINの結合条件に頻繁に登場する列(外部キーの列)
  • インデックスを作成することによるデメリット
    • 索引情報を保存するためにディスク容量を消費する。
    • テーブルのデータが変更されるとインデックスも書き換える必要があるため、INSERT文、UPDATE文、DELETE文のオーバーヘッドが増える。
  • DBMSには連番を管理する機能が提供されている。
  • ACID特性:データを正確かつ安全に取り扱うためにシステムが備えるべき4つの特性。
    • 原子性:処理が中断しても中途半端な状態にならない。
    • 一貫性: データの内容が矛盾した状態にならない。
    • 分離性:複数の処理を同時実行しても副作用がない。
    • 永続性:記憶した情報は消滅せず保持され続ける。
  • ロールバック(実行した処理を取り消す):データベースの利用中に実行失敗やデッドロックなどを要因として度々発生する。
  • ロールフォワード(まだ実行されていない処理を実行する):障害復旧時に行われる処理であるため滅多に発生しない。

「第12章 テーブルの設計」

  • データベース設計の流れ
    • 概念設計:取り扱うエンティティとその関連を明らかにする。
    • 論理設計:キー設計や正規化等を行いRDB用のモデルに変換する。
    • 物理設計:採用するDBMS製品に依存した詳細な設計に落とし込む。
  • 主キーが備えるべき3つの特性
    • 非NULL性:必ず何らかの値を持っている。
    • 一意性:他と重複しない。
    • 不変性:一度決定されたら値が変化することがない。(主キーは、一貫して同じ1行を指し示す。)
  • 正規化
    • 第1正規形:非正規形から繰り返しの列やセルの結合をなくす。
      • 繰り返しの列の部分を別の表に切り出す。
      • 切り出したテーブルの仮の主キーを決める。
      • 主キー列をコピーして複合種キーを構成する。
    • 第2正規形:複合主キーの一部の列に対してのみ関数従属する列をなくす。
      • 複合主キーの一部に関数従属する列を切り出す。
      • 部分関数従属していた列をコピーする。
        第3正規形:主キーに関数従属する列にさらに関数従属する列をなくす。
    • 間接的に主キーに関数従属する列を切り出す。
    • 直接的に関数従属していた列をコピーする。

⚫︎難しく感じた部分

設計の部分が難しく感じました。資料から非正規形にする部分は正解が1つというわけではないため特に難しいと感じました。SQL文についても言えることだと思いますが、とにかく経験を積んで慣れていくことが重要だと思いました。

⚫︎最後に

巻末問題を最後に行いましたが、ボロボロでした😭
もしかしたら各章を終えたごとに問題に取り組んでいったほうがよかったかもしれませんね...。
これから経験を積んで慣れていきたいと思います。
気になった方は是非購入を検討してみてはいかがでしょうか。

Happiness Chainに入会して10ヶ月が経ちました。(1月月報)

皆様こんにちは、Amiaです。

私は「Happiness Chain」というオンラインのプログラミングスクールに入会して勉強しています。

そして「Happiness Chain」に入会してから10ヶ月が経ちました。

それでは10ヶ月目に学習した内容を書いていきたいと思います。

⚫︎自己評価

自己評価は100点中25点です。
今月は学習時間に対する考え方が甘いと感じました。他の方の日報や週報を拝見すると、質も大事ですがやはり圧倒的な時間を学習に充てることが大切だと痛感しました。まだまだ自分に甘かったです。
私は平日2時間、休日5時間を最低目標時間としていますが、来月はこの時間を伸ばしていきたいと思います。

⚫︎10ヶ月目の学習内容(約98時間)

Ruby

①コーディング課題(4)
②コーディング課題(5)

SQL

①動画でのインプット
②書籍でのインプット

⚫︎学習時間について

・1ヶ月目の学習内容(約66時間)
・2ヶ月目の学習内容(約88時間)
・3ヶ月目の学習内容(約88時間)
・4ヶ月目の学習内容(約74時間)
・5ヶ月目の学習内容(約83時間)
・6ヶ月目の学習内容(約82時間)
・7ヶ月目の学習内容(約70時間)
・8ヶ月目の学習内容(約73時間)
・9ヶ月目の学習内容(約56時間(12/21まで))
・10ヶ月目の学習内容(約98時間(1/31まで))
・Happiness Chain入会後累計学習時間(約835時間)

⚫︎成長したこと

Rubyの課題を全てクリアできたこと
Rubyの課題についてメンターの方にペアプログラミングをしてもらいつつですが、先月と合わせてようやくクリアできました。
インプットを始めた時は「本当にできるだろうか...。」と思うことばかりでした。これをやり遂げたということは少しは成長できたのではないかと感じています。
ペアプログラミング、本当にありがとうございます🙏
まだまだ知識不足ですので、これからも日々積み重ねていきたいです。

⚫︎良かったこと

・毎日目標学習時間(mustタスク)を達成できたこと。
・月の後半から英語の学習を習慣化できたこと。

⚫︎悪かったこと

・月の前半は英語の学習を行えていなかったこと。
・コミュニケーション能力向上のために必要な行動が疎かになっていたこと。

⚫︎改善すること(ネクストアクション)

・イベントや雑談会に参加する。
・隙間時間を有効的に使う。

⚫︎感想・来週の目標

・英語の学習を引き続き継続させる。
・コミュニケーション能力向上のために必要なタスクをこなす。

⚫︎1ヶ月振り返ってみての感想

今月は3週間くらいRubyのコーディング課題に取り組み、残りの週はSQLの学習を行いました。
Rubyの課題について進捗が停滞して焦る時もありましたが、なんとかクリアできました。
まだまだ知識不足なため所々復習を挟みつつ、学習を進めていきたいと思います。
次はSQLです。こちらもとても大切な学習なため、また気を引き締め直して臨みたいと思います。

あと英語とコミュ力😨

それではまた遅くて1ヶ月後ぐらいにお会いしましょう🖐️