今日はペースアップして頑張ります。
SQL周りの話だったのでサクサク。railsのactiveRecordでSQL文を少し齧ったから理解が早い。改めて思うがActiveRecordは便利なんだけど、勝手な処理に変換するのでわかりづらい。
DB周りに関しても特につまづくことなく理解した。投資やってたり、家計簿つけてたりでデータに関して多少の知識はあったからかな。今後は実装に入っていくので楽しくペースアップできたらいいな。
先輩からteratailというものがあると聞いたので早速登録してみた。
正直TECHのメンターに聞くよりよっぽど有意義な意見交換ができそう。メンターさんはカリキュラム特化な印象(応用に入ってからはほとんど利用してないけど)。
ruby
for文
doは省略可能。
実行される内容にeachが走るので、指定するオブジェクトはeachを使えるオブジェクトのみ。
for 変数 in オブジェクト do 実行する処理 end
for num in 0..99 do
puts num
end
map
ハッシュに対しても使える。
その場合も返り値はハッシュではなく配列になる。
hogehoge = {id: 5, price: 10}
hogehoge.map { |key, value| [key, value * 2] }
=> [[:id, 10], [:price, 20]]
hogehoge.map { |key, value| [key, value * 2] }.to_h
=> {:id=>10, :price=>20}
map { |key, value| value}
valueだけ取り出した配列が返る。
to_h
ハッシュに変換してくれる
.methods と .methods(:メソッド名).owner
使えるメソッドの一覧を取得。
.ownerでそのメソッドの定義元を確認できる。
a = 5
=> 5
irb> a.methods
=> [:-@, :**, :<=>, :upto, :<<, :<=, :>=, :==, :chr, :===, :>>, :[], :to_int, :coerce, :divmod, :to_s, :to_i, :fdiv, :modulo, :remainder, :abs, :magnitude, :gcd, :integer?, :gcdlcm, :numerator, :lcm, :to_r, :floor, :ceil, :round, :truncate, :rationalize, :to_f, :^, :odd?, :even?, :phase, :imag, :abs2, :arg, :conjugate, :conj, :rectangular]
irb> a.method(:even?).owner
=> Integer
SQL
文末は必ず「;」で終わる。
打ち忘れた場合は改行後に;を打ってenterでOK。
SQL(Structured Query Language)はリレーショナルデータベース(RDB)の操作を行うための言語。
命令は大きく2つ、
データを定義するDDL(Data Definition Language)
データを操作するDML(Data Manipulation Language)
DDLの出来ること
命令 | 機能 |
---|---|
CREATE | データベースやテーブルの作成 |
ALTER | データベースやテーブルの更新 |
DROP | データベースやテーブルの削除 |
・DMLの出来ること
命令 | 機能 |
---|---|
INSERT | データの登録 |
UPDATE | データの更新 |
DELETE | データの削除 |
SELECT | データの検索 |
DB/Tableの操作
terminal
mysqlに接続
なおmysqlを抜ける場合はexit
mysql -u root
データベースを表示
show databases;
CREATE DATABASE文
データベースを作る
CREATE DATABASE データベース名;
USE文
データベースを選択する
USE データベース名;
SHOW TABLES文
選択したデータベースに存在するテーブルを一覧で表示する
SHOW TABLES;
CREATE TABLE文
テーブルを作成する
CREATE TABLE テーブル名 (カラム名 カラム名の型, ……);
mysqlで数字型や文字列型を定義する際は以下のような型名を使用する。
型名 | 保存できる値 |
---|---|
INT | 数字 |
VARCHAR(M) | 最大M文字の文字列 |
CREATE TABLE goods (id INT, name VARCHAR(255));
SHOW COLUMNS FROM
テーブルのカラムを表示する。
SHOW columns FROM テーブル名;
ALTER TABLE
カラムの追加
ALTER TABLE テーブル名 ADD カラム名 カラムの型;
ALTER TABLE テーブル名 ADD (カラム名 カラムの型, ……);
カラム名や型の変更
ALTER TABLE テーブル名 CHANGE 古いカラム名 新しいカラム名 新しいカラムの型;
この際、名前の変更のみをする場合でも型は入力しなければならない。
カラムの削除
ALTER TABLE テーブル名 DROP カラム名;
データの操作
INSERT文
全てのカラムに値を入れる場合
INSERT INTO テーブル名 VALUES(値1, 値2, 値3);
特定のカラムのみに値を入れる場合
INSERT INTO テーブル名(カラム名1, カラム名2) VALUES(値1, 値2);
データの取得
SELECT * FROM テーブル名;
UPDATE文
値の変更
UPDATE テーブル名 SET 変更内容 WHERE 条件;
例
UPDATE goods SET price = 100 WHERE id = 2;
DELETE文
DELETE FROM テーブル名 WHERE 条件;
データの検索
*
ワイルドカード
FROM句
テーブルを選択
FROM テーブル名
SELECT句
SELECT カラム名
WHERE句
WHERE 条件
例
WHERE id = 1
WHERE family_name = "ほげほげ"
WHERE id <= 8
演算子
AND演算子
A かつ B
WHERE a AND b
OR演算子
A または B
WHERE a OR b
NOT演算子
A ではない
WHERE NOT a
BETWEEN演算子
WHERE カラム名 BETWEEN 下限 AND 上限
例
WHERE age BETWEEN 20 AND 30
IN演算子
リストを指定し、カラムの値がそのリストに含まれるときにtrue
WHERE カラム名 IN (値1, 値2, ……)
例
WHERE prefecture IN ("東京都", "神奈川県")
関数
CONCAT関数
concatenateの略。意味は鎖状に繋ぐ。
転じて、複数の文字列を結合できる。
nullが含まれる場合、結合した文字列はnullとなる。
CONCAT(文字列1, 文字列2, ……)
例
SELECT CONCAT(family_name, first_name)
FROM users
AS句
SELECT句でデータを取得する時に、AS句を併用するとカラムに別名を付けられる。
SELECT 取得するデータ AS 別名
例
SELECT CONCAT(family_name, first_name) AS fullname
FROM users
ASは省略できるため、実際にはselectに続けて表記したいカラム名を書く。
SELECT CONCAT(family_name, first_name) "名前"
DISTINCTキーワード
指定したカラムの値が重複する行を除外してデータを取得できる。
distinct 違う、はっきり異なる。
SELECT DISTINCT カラム名
例
SELECT DISTINCT user_id
FROM shifts
WHERE date = "2015-07-01"
GROUP BY句
同じ値を持つデータを1つのグループとしてまとめる。
distinctと異なり、グルーピングしているだけなのでグルーピング内のデータも保持しているため、グループ内のデータ処理も可能。
GROUP BY カラム名
COUNT関数
カラムを指定して使用し、値がnullでないデータの行数を取得する。
SELECT COUNT(カラム名)
カラム名にワイルドカードを指定すれば、nullを含む全レコードの件数を取得する。
SELECT COUNT(*)
AVG関数
MAX関数
MIN関数
テーブルの結合
inner joinとouter join
outer joinは優先テーブルを指定する。
優先テーブルに指定されたテーブル内の要素は全て出力され、対応するjoin先の項目がなければnullが入る。
FROM users JOIN reviews
の左か右のどちらのテーブルを指定するかで、left join/ right joinがある。
inner joinは優先テーブルを考慮しない。
考慮しないため、項目の少ないテーブルに項目数の多いテーブルをjoinした場合、項目数の多いテーブルに合わせてテーブル内容がコピーされてデータ数が増える。
この際、結合先がnullのデータは無視される。
以下のようなテーブルを結合した場合
users id name
1 aa
2 bb
reviews id text user_id
1 ttt 1
2 yyy 1
3 uuu 3
FROM users JOIN reviews ON users.id = reviews.user_id
users id name r.id r.text r.user_id
1 aa 1 ttt 1
1 aa 2 yyy 1
JOIN
無記名のjoinは常にinner joinを示す。
指定したそれぞれのテーブルの、カラムの値が一致するデータを結合できる。
JOIN句はFROM句のあとに記述し、結合の対象となるテーブルを指定する。
FROM テーブル名1
JOIN テーブル名2 ON テーブル名1.カラム名1 = テーブル名2.カラム名2
サブクエリ
ある検索結果を使用して別のSQL文を実行する仕組み
SELECT *
FROM users
WHERE id NOT IN (
SELECT DISTINCT user_id
FROM shifts
WHERE date = "2015-07-01"
)
database総論
キー
- 主キー
- 外部キー
制約
- NOT NULL制約
- 一意性制約
- 主キー制約
- 外部キー制約
null制約
migrationファイルでnull制約をかける。
t.string :name, null: false
一意性制約
migrationファイルにadd_indexでuniqueにする。
class AddEmailToUsers < ActiveRecord::Migration
def change
add_column :users, :email, :string
add_index :users, :email, unique: true
end
end
主キー制約
not null制約と一意性制約を同時にかけるのと同義。
もともとid行として設定されている。
外部キー制約
外部キーに対応するレコードが必ず存在することを保証する制約
t.references :user, foreign_key: trueとすることでuser_idがカラムに追加され、外部キーとして設定される。
class CreateScores < ActiveRecord::Migration
def change
create_table :scores do |t|
t.string :name
t.integer :score
t.references :user, foreign_key: true
t.timestamps null: false
end
end
end
インデックス
カラムに対して設定する。検索の高速化を目的に行う。
以下のデメリットがあるため、インデックスを貼るのは必要最低限で。
- データを保存・更新する速度が遅くなる
- データベースの容量を使う
class AddIndexToテーブル名 < ActiveRecord::Migration
def change
add_index :テーブル名, :カラム名
end
end
複数のカラムに貼る場合は
add_index :テーブル名, [:カラム名, :カラム名]
複数のカラムに対してインデックスを貼った場合は、この2種を同時に用いた検索の時に処理が早くなる。言い換えると、カラム単独の検索を行ってもインデックスがないので早くない。
has_many throughオプション
through: :photos_tags 両方ともシンボル
多対多を解消する際に用いる。
顧客ー注文ー商品のようなテーブル構造にした際、連携するテーブルと中継テーブルをhas_manyで連携し、なおかつ中継テーブルはthroughオプションを使う。
# app/models/photo.rb
class Photo < ActiveRecord::Base
has_many :photos_tags
has_many :tags, through: :photos_tags
end
# app/models/tag.rb
class Tag < ActiveRecord::Base
has_many :photos_tags
has_many :photos, through: :photos_tags
end
# app/models/photos_tag.rb
class PhotosTag < ActiveRecord::Base
belongs_to :photo
belongs_to :tag
end
オプション名 | 用途 |
---|---|
class_name | 関連するモデルのクラス名を指定でき、関連名(photos_tags等、has_manyの直後に書くもの)と参照先のクラス名(PhotosTagのようなモデル名)を異なるものにできる |
foreign_key | 参照先を参照する外部キーの名前を指定できる(デフォルトは、参照先のモデル名_id) |
dependent | 親モデルのデータを消したら関連するモデルのデータも連動して消したいときに使用します。destroyとdelete_allでひとつひとつ消していくか、一気に消すかを指定できる |
source | 関連テーブルから先のモデルにアクセスするための(関連モデルから見た)関連名を指定できる |
README
マークダウンで記述され、ソフトウェアの仕様、規格、インストール方法などを文書化したもの。rails newをした際に自動的に作成される。
## membersテーブル
|Column|Type|Options|
|------|----|-------|
|user_id|integer|null: false, foreign_key: true|
|group_id|integer|null: false, foreign_key: true|
### Association
- belongs_to :group
- belongs_to :user
SequelPro
クエリにsql文を打っても文末の;を打つ必要はない。
コメント