「達人に学ぶSQL徹底指南書」ふりかえり
この本読んで思ったことや大事だと思った箇所のメモ
例題や問題とその意図を記載することにより、後から理解しているか、覚えているかを確認する意図で記載していく
書籍を読んで思ったこと箇条書き
- この本はSQLの研修を受けて、仕事でも使ってるけどなんか良く分からんみたいな人には結構オススメ
- WINDOW関数についてそろそろ学ばなきゃ、みたいに思ってる人にもオススメ
- WINDOW関数は普通のプログラミングの見方を持っていると、他の書き方よりもとっつきやすい
- さよなら相関サブクエリ、こんにちはWINDOW関数
- CASE式の強力さに触れられる
- 集合論からみたSQL, 述語論理からみたSQL
- 他の言語以上に闇が深いSQLのNULL
1章 CASE式のススメ
所感
要約
- CASEは文ではなく「式」
- 列名や変数を書ける場所ほぼ全てに書ける
- 実装非依存かつ高い表現力を持つ
コード体系の変更
- 選択したい行の形をCASEを用いて表現する
- SELECT句とGROUP BYに同条件を指定すると実現可能
- (SQLの範囲で取りたい断面で情報の取得が可能)
1. 行持ちを列持ちに
- 集約関数の引数にCASE式で条件に当てはまるものだけ対象にする
- SELECT句に別名をつけて、GROUP BYで使える実装もある
pref_name | sex | population |
---|---|---|
徳島 | 1 | 60 |
徳島 | 2 | 40 |
香川 | 1 | 100 |
香川 | 2 | 100 |
・・・ | ・・・ | ・・・ |
↓
pref_name | 男 | 女 |
---|---|---|
徳島 | 60 | 40 |
香川 | 100 | 100 |
・・・ | ・・・ | ・・・ |
2. 表のクロス表作成
- 以下の2表からクロス表作成
- CASE式の条件をサブクエリで実現する
CourseMaster
id | name |
---|---|
1 | SQL入門 |
2 | 財務知識 |
・・・ | ・・・ |
OpenCourses
month | id |
---|---|
201806 | 1 |
201806 | 3 |
201806 | 4 |
201807 | 1 |
・・・ | ・・・ |
↓
クロス表
コース名 | 6月 | 7月 | 8月 |
---|---|---|---|
SQL入門 | ○ | ○ | ☓ |
・・・ | ・・・ | ・・・ | ・・・ |
3.CASE式の中で集約関数
- 1つのクラブのみに所属している人はHAVING, 複数の場合はmain_clug_flgで選択可能
- CASE式の中で集約関数を使えば、HAVING句を書かなくても同等の処理が出来る
std_id | club_id | club_name | main_club_flg |
---|---|---|---|
100 | 1 | 野球 | Y |
100 | 2 | 吹奏楽 | N |
200 | 2 | 吹奏楽 | N |
200 | 3 | バドミントン | Y |
200 | 4 | サッカー | N |
300 | 4 | サッカー | N |
400 | 5 | 水泳 | N |
500 | 6 | 囲碁 | N |
↓
std_id | main_club |
---|---|
100 | 1 |
200 | 3 |
300 | 4 |
400 | 5 |
500 | 6 |
2章 必ずわかるWINDOW関数
所感
- 相関サブクエリより読みやすいしパフォーマンスも良い
- 一部が実行出来るの大きなメリット、仕事でもガンガン使っていきたい
- 少し古いバージョンのPostgresql使っていると機能足りなかったりする
- mysqlは対応が遅いため、なにか足りなかったりすることが多い(らしい)
要約
- 主要なRDBMSがWINDOW関数を実装した
- WINDOW関数の機能は以下のように説明出来る
- PARTITION BY句は集約しないGROUP BY、レコード集合のカット
- ORDER BY句によるソート
- フレーム句によるレコードを中心としたサブセット定義
3章 自己結合の使い方
所感
- 集合を作るために自己結合を活用する、という観点は興味深い
要約
- マスタの組み合わせを得たい時など、重複順列、順列、組み合わせを自己結合で実現出来る
- 重複の排除(DELETE文の利用)も自己結合を上手く使うと実現可能
- rowid使って1つだけ残すような感じ
- 自己結合を非等値結合と組み合わせて使う
- 部分的に不一致なものを取得する
- 同じ値段のもの(=名前が違うもの)みたいな感じで取れる
- GROUP BYと組み合わせると再帰的集合を作ることが出来る
4章 3値論理とNULL
所感
- 第一版を読んだ時に最も印象に残った章
- unknownという地獄
- NULLは使わないようにしたい、と思うけどまぁどうでも良いところには使ってしまう
- NOT NULL制約は付けられる場合には付与すべきと思わされる
要約
NOT INとNOT EXISTSでは同値変換出来ない
- NULLが入ると、NOT INは条件がunknownになる
- EXISTSはtrueかfalseかのどちらかしか返さない
極値関数を使うと、NULLが入っていてもうまく無視してくれる
5章 EXISTS述語の使い方
所感
- 2回目読んだ中で一番印象的な章の一つ
- この章、SQL本として有用なのはもちろんだが読み物としても面白い
- 全称量化に気づくのがまずムズイ
要約
- データベースにおける行はデータでなく命題
- 述語とは戻り値が真理値になる関数
- EXISTSは二階の述語
- データが無い行、というような条件を探す場合には、理想的な状態(=全部入りの状態)をCROSS JOIN等 で作成し、そこからNOT EXISTSなり、EXCEPTなりで絞り込む
- 全称量化「全ての行について〜」を「〜でない行が1行も存在しない」に置き換える
- 列方向への全称量化、存在量化は対応する関数がある
テストの点数条件絞り込み
std_id | subject | score |
---|---|---|
100 | 算数 | 100 |
100 | 国語 | 80 |
100 | 理科 | 80 |
200 | 算数 | 80 |
200 | 国語 | 95 |
300 | 算数 | 40 |
300 | 国語 | 90 |
・・・ | ・・・ | ・・・ |
- 全ての科目が50点以上の生徒を抽出
- DISTINCTしない結果を考える、id300の国語は何故出力されないのか
- 数学が80点以上、国語が50点以上の生徒を抽出
- どちらも点数がある場合のみを条件に
6章 HAVING句の力
HAVING句は集合指向言語の観点から見ると強力
count()とcount(col_1)の結果は異なる
col_1にNULLが入って居た場合にはカウントされないが の場合は例え1列しかなくてもカウントされる
GROUPに1種類しか存在しない、を表現する場合には以下の3種類の方法がある
1. NOT EXISTSで書く 2. HAVINGで特性関数のようなものと個数を比較する 3. HAVINGで評価したい値のMAXとMINが一致する
GROUP内に重複が無いもの、を表現する場合には対象列の個数と対象列をDISTINCTした結果が一致するかを比較する
バスケット解析 item | item | |:-------| |ビール| |紙おむつ| |自転車| |・・・|
ShopItem | std_id | subject | |:-----------|:------------:| |仙台|ビール| |仙台|紙おむつ| |仙台|自転車| |仙台|カーテン| |東京|ビール| |東京|紙おむつ| |東京|自転車| |大阪|テレビ| |大阪|紙おむつ| |大阪|自転車|
- Itemに含まれるものを全て取り扱っている店舗を取得
- 取り扱っているものが過不足なくItemの項目と一致する店舗を取得
Slackで二要素認証用のデバイスが死んで、パスワードも忘れ、リカバリコードも失った時の復旧方法
管理者に連絡すれば良いと思ったが、スマホを失うと連絡する方法が無かったりする
この方法で復旧できる前提
- ログインしようとしているSlackワークスペースがfree plan もしくは有償プランでも二要素認証が強制されていないワークスペース
- どこかのPCでログインセッションが生きている
- リカバリコードを使い切っていない
この条件を満たす場合上記管理者に連絡せずに復旧できる(2018年8月現在)
手順
- 自分のユーザーアイコン > Open account settings > Accountページ
- Two-Factor Authenticationのexpandボタンクリック
- You have 10 unused backup codesからリカバリコードをコピー
- Passwordのexpandボタンクリック
- Reset your password by Email
- mailから、新しいパスワードと共に二要素認証のコードを求められるので、上記のリカバリコードを入れてパスワード変更
- パスワードを更新したらdisable Two factor authentication から一度二要素認証を無効にする
- 直後に再度 Enable Two factor authenticationから、新しいデバイスで再度二要素認証を有効にする
スマホが海にダイブして、一番不安になったのはSlackにログイン出来なくなったことでした
とりあえず検索でこんな記事が有用になっちゃったあなたは悪いことは言わないからAuthyを使おう
リカバリコードさえどこにあるか分からん時点で君はまた携帯壊すって
Spring Boot(Gradle)プロジェクトをIntelliJ Community Editionで起動するまで
はじめに
IntelliJ Community EditionでGradleプロジェクトのSpring Bootを取り込む方法が見つけられなかったのでまとめた
普段仕事ではEclipse使っているが、Eclipseだけ使っていると
これじゃない気がするが、あるべき姿が良くわからない
という問題に陥る
IntelliJを使うことでこの問題解消出来たら良いな
Java
MacだとWindowsと違いすぎて不安になる
とりあえず最新で入れた
.bash_profileには以下のような感じで
export JAVA_HOME=`/usr/libexec/java_home -v 10`
$ java -version java version "10.0.1" 2018-04-17 Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10) Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)
Java10にしてみた
Spring Boot(ver. 2.0.3)
Spring Initializr
まずはSpring Initializrで色々入れる、知っているやつ色々入れてみた
- PostgreSQL
- Spring Integration
- Thymeleaf
- flyway
IntelliJ(Version 2018.1.5)
基本的に設定はデフォルト、Use auto-import だけonにしている
Gradle wrapper(= gradlew)を使用
Gradleが使うJavaをJava10に変更
アプリ起動
ヘッダーのRun > Run
デフォルトのアプリ動かすだけで割と時間を食ってしまった...
IntelliJはTipsとか見ながら慣れていくことにする
その他
上記構成だと起動は出来るが起動時に以下の警告が出る Spring coreで不適切なリフレクションを使っている? 家で遊ぶだけだからとりあえず放置
2018-07-08 00:02:09.802 INFO 10799 --- [ main] o.s.i.config.IntegrationRegistrar : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created. WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/Users/urara/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.0.7.RELEASE/54b731178d81e66eca9623df772ff32718208137/spring-core-5.0.7.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
RSpec備忘録
この記事の目的
- rspec 3.1の書き方に慣れる
- 今度使う時のリファレンス用
今回使うバージョン
今回のタスク
1行に1つの整数が入っているファイルを読み込んで
- 和を出したり
- 平均出したり
- 新たな配列作ったり
実際のコード
手順メモ
いつものプロジェクト準備
spec書く前作業
bundle init # Gemfileにrspec取る記述 bundle install rspec --init # .rspecに「-format d」追記(個人的な好み) mkdir spec/
TDD始める
- spec/score_spec.rbから書く
書き方関連
it とspecify
参考: るびま
- どうやらitは過去specifyを使っていたらしい
- specifyは今も有効
- itだと日本語だと違和感があるのでspecify使った物も多い
- 個人的には
- type数が少ないitで良い
- 混ざる位なら全部itで良い
describeとcontext
参考: るびま
アンダースタンディングコンピューテーション 2章
下の書籍2章の話
https://www.amazon.co.jp/dp/487311697X
※ 読んでる時に書いたメモです、アンダースタンディングコンピューテーションを要約するようには書いていません。
第一部 プログラムと機械
計算
計算には以下の要素が必要
- 計算を行う機械
- 機械が解釈できる言語
- 言語によって書かれる実行すべき計算を表すプログラム
意味論とは?
言葉と意味の関係に関する学問
形式的意味論
プログラミングの意味を明確にし、プログラミングに関する興味深い事を発見する
→ 数学のトポロジーみたいな感じかな?
プログラミング言語の仕様を完全に記述するには
- 構文(どのように見えるか)
- 意味論(何を意味するか)
が必要
プログラミングの言語の仕様
実装による仕様
Rubyもこれ
→MRI(Matz's Ruby Interpreter)によって定義、JRubyやMacRuby等はMRIの振る舞いと完全に一致する必要がある
公文書による仕様
JavaやECMAScript
専門家によって十分に議論されたドキュメントにより仕様を定義
形式意味論による仕様
数学的手法によりプログラミング言語の意味を正確に記述する
構文とは?
特定の言語により有効なプログラムであるかを判定する規則
→パーサにより判断
パーサの役割はASTを作成する事
= 構文上問題ない場合(ASTが問題なく作られる場合)でもプログラムとしては問題がある状態がある
# AST作れるけど、プログラム的には問題がある例 y = x + 1
操作的意味論
- プログラムがある種のプログラム上でどのように実行されるのか、規則を定義する
- プログラム言語毎に異なる抽象機械が必要
スモールステップ意味論
- 構文を小さなステップに簡約することで、プログラムを評価する機械を考える
- 評価出来る部分から評価する
四則演算のふるまい記述
class Number < Struct.new(:value) def to_s value.to_s end def inspect "<<#{self}>>" end def reducible? false end end class Add < Struct.new(:left, :right) def to_s "#{left} + #{right}" end def inspect "<<#{self}>>" end def reducible? true end def reduce if left.reducible? Add.new(left.reduce, right) elsif right.reducible? Add.new(left,right.reduce) else Number.new(left.value + right.value) end end end class Multiply < Struct.new(:left, :right) def to_s "#{left} * #{right}" end def inspect "<<#{self}>>" end def reducible? true end def reduce if left.reducible? Multiply.new(left.reduce, right) elsif right.reducible? Multiply.new(left, right.reduce) else Number.new(left.value * right.value) end end end
同様な感じで他の四則演算記号や"<"やBool値等も作れる
変数
変数の機能を持つためには、仮想機械は現在の式の他に環境(environment)を持つ必要がある
→#reduceをenvironmentを引数に取るように変更、仮想機械は自身の式の中に変数が出てきたらenvironmentを探して簡約する
こんな感じ
class Variable def reduce(environment) environment[name] end end # 各#reduceは以下の様な感じに変更 def reduce(environment) if left.reducible? Add.new(left.reduce(environment),right) end ・・・ end
if文
こんな感じ
class If < Struct.new(:condition, :consequence, :alternative) ・・・ def reduce(environment) ・・・ case condition when Boolean.new(true) [consequence, environment] when Boolean.new(false) [alternative, environment] end end end
while文
if文に置き換える事で解決 こんな感じ (SequenceとDoNothingは書籍参照)
class While < Struct.new(:condition, :body) ・・・ def reduce(environment) [If.new(condition, Sequence.new(body, self), DoNothing.new), environment] end end
ビックステップ意味論
- ビックステップはASTを一度走査することで、どうやってプログラム全体の結果を計算するかを記述
- スモールステップよりも大雑把な感じ(再帰で一片に解決する)
※載せると長くなるので省略
OCamlのコア言語はビックステップで説明されている
式と文
- 文はそれ単体で完結する → 評価された時に戻り値を捨てる
- 式は何かの一部 → 評価された時の戻り値を使う
だから、SQLのCASE式というのは評価され何かに置き換わる →どこにでも書ける
式
- 評価されることで別の式を生成
- スモールステップではreduce出来ない所までreduceする
- 式をreduceして新たな式を作る、これをreduce出来ない所まで繰り返す
- 今までやっていた例は全ての部分が式
文
評価されることで抽象機械のenvironmentを変更
代入では
x = x + 1
の場合、右辺が式、全体は文になる
- 文の評価は、右辺がreduce出来るか見て、出来ればreduce、出来なければ代入を行う
- 文の評価によって、初めて状態が変更される
表示的意味論
- プログラムをネイティブ言語から別の表現に変換
- 「Rubyで書くとこんな書き方〜」
walkの意味を伝える場合 - 実際に歩いてみせる(操作的) - 「歩く」の英語表現、等と既に知っているであろう知識とマッピングする(表示的)
Rubyで書いたため実行可能であるが、例えば「数式」「英語」等で表される場合にはもちろん無理
まとめ的なもの
今までの動作の違い
今までの違いを見るにはwhileの動作を見るとわかりやすい
スモールステップ意味論のwhile
- 抽象機械の簡約規則として書かれる
- ループとしての振る舞いは出てこない スモールステップ意味論から言語を理解するには、スモールステップ規則を全て調べ、それがどのように作用するか見る
ビックステップ意味論のwhile
- 最終的な環境を直接計算する方法が書かれる
- どのように振る舞うかはWhileの記述を見ればわかるが、これを見ただけでは環境がどのように変更されるか等が分からない
表示的意味論のwhile
実際の形式意味論
形式意味論の重要な応用は
【Ruby】UTF-16でエンコードされたファイルを扱う方法
#UTF-16でエンコードされたファイルをUTF-8に変更する方法について
※Ruby 2.0.0-p247で動作(どのバージョンから動くのかは調べていない)
調べるとiconvを使う方法やnkfを使う方法等情報が混在していたため、備忘録がてらまとめておく
以下の例では、ディレクトリ以下にある全てのUTF-16でエンコードされたファイルをUTF-8に変更する。
def trans_utf8(path) Dir::glob(path).select{|item| File.file?(item)}.each do |file| File.open(file, 'r'){ |f| buffer = f.read(); buffer = buffer.encode("UTF-8", "UTF-16", :invalid => :replace, :undef => :replace, :replace => '*') f = File.open(file, 'w') f.write(buffer) } end end
fileもう一回開きなおしたらclose要るのかな?確認する。
パーフェクトRuby 2章
#第二章
簡潔にまとまってるのでreferenceに良いかも、忘れた頃にもう一回読んでも良いかも
以下、曖昧だった箇所、初めて知った事
##スコープ
### ローカル変数
- JavaScriptを弄った後いつも混乱するからまとめ
- Rubyのスコープはブロック > メソッド定義 > クラス定義 > トップレベルで作られる
- ローカル変数はスコープ毎に定義され、外の変数は見えない(こうあるべきよね)
- ブロックのみ例外で、外にあるローカル変数触れる
※外からブロック内に定義されたローカル変数には(もちろん)触れない
##真偽値
- Rubyではfalseとnilのみが偽、他は全て真
- JavaScriptのようにundefinedとnilの区別が無いため、例えば配列の要素取り出したらnilだった場合
1.何も入らなかった
2.入っていた値がnilだった
の切り分け作業が発生する。
というかそんな切り分けが起きないようにコーディングしましょうっていう事(なんでしょうきっと)
##self
- Rubyのselfはインスタンス自身を返す(Java等のthisと同じ)
- クラス内でレシーバを書かずメソッド名を書いた場合selfがレシーバとなる
- 基本的にselfは書かなくて良いが、インスタンス変数への代入では、selfを書かなかった場合、ローカル変数宣言になってしまう
##Arrayの宣言
%i(red green blue) #=> [:red, :green, :blue]と一緒
※Ruby2.0から
##多重代入
これを使うと変数の交換が以下の記述でいける
a, b = b, a
##自己代入
Rubyに無いと思ってた、なんでだろう?
a ||= 2
と書くとaがnilまたはfalseであった場合aに2を代入という意味
nullチェックが簡単に書ける、と