Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ITエンジニア怪談 ~背筋も凍る、ゾッとする話Night~

478 views

Published on

ITエンジニア怪談 ~背筋も凍る、ゾッとする話Night~

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

ITエンジニア怪談 ~背筋も凍る、ゾッとする話Night~

  1. 1. Copyright 2016-2018 G1Systems Inc. 定時を22時にしてください 基本構文を知らずに起きたデスマーチ! 1
  2. 2. Copyright 2016-2018 G1Systems Inc.2 SQLおじさん、改め、 チコちゃん 50-歳です。 今日のお話は、チコちゃんに叱られる ようなことをしていると、 「とんでもないデスマーチになる」 というお話です。 ※ 某公共放送のチコちゃんとは無関係です。
  3. 3. Copyright 2016-2018 G1Systems Inc.3 さっそく例題 すべての生徒のリストに、特待生マスタの削除フラグが 0 の 特待生ランクを付加して出力する SQL を書いてください。 2 C 生徒ID ランク 3 A 10 B 33 C 40 B 48 C 1石野 扶樹 ID氏名 2岩崎 研二 3岩間 竜也 4上野 浩介 5岡崎 雅之 6岡島 慶二 生徒マスタ 特待生マスタ 1 削除フラグ 0 0 0 0 0
  4. 4. Copyright 2016-2018 G1Systems Inc. 解答欄 4 SELECT a.氏名, b.ランク FROM 生徒マスタ a LEFT OUTER JOIN 特待生マスタ b ここに結合条件を追加 これを出力 したくない 生徒マスタ 特待生マスタ 2 C 生徒ID ランク 3 A 10 B 33 C 40 B 48 C 1石野 扶樹 ID氏名 2岩崎 研二 3岩間 竜也 4上野 浩介 5岡崎 雅之 6岡島 慶二 1 削除フラグ 0 0 0 0 0
  5. 5. Copyright 2016-2018 G1Systems Inc. 解答例 5 SELECT a.氏名, b.ランク FROM 生徒マスタ a LEFT OUTER JOIN 特待生マスタ b ON a.ID = b.生徒ID WHERE b.削除フラグ = 0;
  6. 6. Copyright 2016-2018 G1Systems Inc.6
  7. 7. Copyright 2016-2018 G1Systems Inc. 間違いです 7 WHERE 削除フラグ = 0 では、 削除フラグが 0 の のレコードだけになる。 ← NULL = 0 は False ← NULL = 0 は False ← NULL = 0 は False 生徒マスタ 特待生マスタ 2 C 生徒ID ランク 3 A (4) NULL (5) NULL (6) NULL 1石野 扶樹 ID氏名 2岩崎 研二 3岩間 竜也 4上野 浩介 5岡崎 雅之 6岡島 慶二 1 削除フラグ 0 NULL NULL NULL ← NULL = 0 は False 10 B 33 C 40 B 0 0 0 (1) NULL NULL ← 1 = 0 は False
  8. 8. Copyright 2016-2018 G1Systems Inc. つまり、これはバグ(外部結合が必要か判別不能) 8 SELECT a.氏名, b.ランク FROM 生徒マスタ a LEFT OUTER JOIN 特待生マスタ b ON a.ID = b.生徒ID WHERE b.削除フラグ = 0; 外部結合を打消し てしまう。
  9. 9. Copyright 2016-2018 G1Systems Inc. 例えば、WordPress 4.9.4 での例 if ( $post_status_join ) { $join .= “ LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID)"; foreach ( $statuswheres as $index => $statuswhere ) { $statuswheres[$index] = "($statuswhere OR ({$wpdb->posts}.post_status = 'inherit’ AND ".str_replace( $wpdb->posts, 'p2', $statuswhere ) . "))"; } } $where_status = implode( ' OR ', $statuswheres ); if ( ! empty( $where_status ) ) { $where .= " AND ($where_status)"; } ※ class-wp-query.php 9
  10. 10. Copyright 2016-2018 G1Systems Inc. WordPress 4.9.4 は、最後に LEFT JOIN に変換 /** Generates SQL clauses to be appended to a main query. -- 中略 -- public function get_sql( $type, $primary_table, …… -- 中略 -- /* If any JOINs are LEFT JOINs (as in the case of NOT EXISTS), then all JOINs should be LEFT. Otherwise posts with no metadata will be excluded from results. */ -- 中略 -- if ( false !== strpos( $sql['join'], 'LEFT JOIN' ) ) { $sql['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $sql['join'] ); } -- 中略 -- ※ class-wp-meta-query.php 10
  11. 11. Copyright 2016-2018 G1Systems Inc.11
  12. 12. Copyright 2016-2018 G1Systems Inc. 一応、Word Press がやっている変換意図を解説 12 生徒マスタ 特待生マスタ 2 C 生徒ID ランク 3 A (4) NULL (5) NULL (6) NULL 1石野 扶樹 ID氏名 2岩崎 研二 3岩間 竜也 4上野 浩介 5岡崎 雅之 6岡島 慶二 1 削除フラグ 0 NULL NULL NULL 10 B 33 C 40 B 0 0 0 (1) NULLNULL ランク名称マスタ 学業特待生AA 名称ランク 学業特待生BB スポーツ特待生C こちらINNER JOIN にすると、 B・Cに一致するものがない ため、外部結合を打消してし まう。こちらを LEFT JOIN
  13. 13. Copyright 2016-2018 G1Systems Inc. サブクエリ にすると正しく出ます 13 SELECT a.氏名, b.ランク FROM 生徒マスタ a LEFT OUTER JOIN (SELECT * FROM 特待生マスタ WHERE 削除フラグ = 0) b ON a.ID = b.生徒ID;
  14. 14. Copyright 2016-2018 G1Systems Inc. 件のプロジェクトは……10年前の話  COBOL から Java へのマイグレーション案件  数百GByte(当時としてはかなり大きい)  テーブル数 400個(マスタは200個ほど)  マスタに一意になるキーがない!  キーと有効期限で絞り込むと一意になる。  LEFT JOIN決打ちで、サブクエリにするのが共通仕様  サブクエリの SELECT句で「*」禁止  数千を超えるサブクエリの詳細設計書を書きレビュー 14
  15. 15. Copyright 2016-2018 G1Systems Inc.15
  16. 16. Copyright 2016-2018 G1Systems Inc.16 今こそ 全てのエンジニアに 問います。
  17. 17. Copyright 2016-2018 G1Systems Inc.17 基本構文の JOIN すら 正しく理解せずに、
  18. 18. Copyright 2016-2018 G1Systems Inc.18 やれ、 ORMを 知っていれば充分だの
  19. 19. Copyright 2016-2018 G1Systems Inc.19 これからは NoSQLの時代
  20. 20. Copyright 2016-2018 G1Systems Inc.20 などと浮かれている エンジニアの なんと多いことか。
  21. 21. Copyright 2016-2018 G1Systems Inc.21 しかし、チコちゃんは 知っています。
  22. 22. Copyright 2016-2018 G1Systems Inc.22 削除フラグ = 0 は、 抽出条件ではなく、 結合じょ~けんンン!
  23. 23. Copyright 2016-2018 G1Systems Inc. つまりサブクエリではなく、こうする! 23 SELECT a.氏名, b.ランク FROM 生徒マスタ a LEFT OUTER JOIN 特待生マスタ b ON a.ID = b.生徒ID AND 0 = b.削除フラグ;
  24. 24. Copyright 2016-2018 G1Systems Inc. 有効期限のときはこうする! 24 SELECT a.氏名, b.ランク FROM 生徒マスタ a LEFT OUTER JOIN 特待生マスタ b ON a.ID = b.生徒ID AND 基準日 >= b.有効期限From AND 基準日 <= b.有効期限To;
  25. 25. Copyright 2016-2018 G1Systems Inc. 基本構文すら知らず、阿鼻叫喚の地獄絵図に…… 25 定時を20時に(20時までに帰るときは上長に届け出) 度重なるリスケ(予定の倍以上) 更に、定時を22時に変更 最大200人以上のエンジニアが常駐 開発費が、予算の10倍以上に膨れ上がる。 把握されているだけで7名が入院
  26. 26. Copyright 2016-2018 G1Systems Inc. ご依頼ください 自分もやってるかも……。という方は、 診断・チューニング・出張セミナーなど ご依頼ください。 よろしくお願いいたします。 s.ikushima@g1sys.co.jp 26
  27. 27. Copyright 2016-2018 G1Systems Inc. おまけ(よくある勘違い) 27 JOIN は遅い JOIN は負荷がかかる 正しい
  28. 28. Copyright 2016-2018 G1Systems Inc. おまけ(間違った対処) 28 JOIN を使わない 間違い 遅く、負荷も高まる
  29. 29. Copyright 2016-2018 G1Systems Inc. おまけ(正しい対処) 29 JOIN しないために 非正規化する 非正規化に伴う デメリットとトレードオフ

×