Monthly Archives: 1月 2014

「SQLアンチパターン」第22回 (1/31)

Posted on by 0 comment

参加者 沼田(読み手)、今井(記)

範囲 pp.205-218

IV部 アプリケーション開発のアンチパターン

  • 19章 リーダブルパスワード(読み取り可能パスワード)
    • 19.1 目的:パスワードのリカバリーとリセットを行う
    • 19.2 アンチパターン:パスワードを平文で格納する
      • 19.2.1 パスワードの格納
      • 19.2.2 パスワードの認証
      • 19.2.3 パスワードを電子メールで送信する
    • 19.3 アンチパターンの見つけ方
    • 19.4 アンチパターンを用いてもよい場合
      • p.211 囲み最後 Sinsという単語の意味は?
        → 罪。七つの大罪(Seven deadly sins)からきている?
    • 19.5 解決策:ソルトを付けてパスワードハッシュを格納する
      • 19.5.1 ハッシュ関数を理解する
      • 19.5.2 SQLでのハッシュの使用
      • 19.5.3 ハッシュにソルトを加える
        • p.214 salt.sql
          • パスワードハッシュ値とソルトを一緒においておくと、そのハッシュ値を用いてパスワードを試すことが出来るのではないだろうか。p.213 dictionary-attack.sqlのような、あらかじめハッシュ値化したテーブルを使うことはできないが。
          • BINARY型はどんな型?
            非文字を含んだバイナリ列を保存できる型。
      • 19.5.4 SQLからパスワードを隠す
      • 19.5.5 パスワードをリカバリーするのではなく、リセットする

「SQLアンチパターン」第21回(1/28)

Posted on by 0 comment

参加者 今井(読み手)、青木、沼田(記)
範囲 pp.192 – 203

III部 クエリのアンチパターン

  • 17章 スパゲッティクエリ
    • 17.5 解決策:分割統治を行う
      • 17.5.2 UNIONを用いる
        • LEFT OUTER JOIN
          OUTERは省略できる
        • UNION ALL
          ALLをつけないと重複レコードは削除される
      • 17.5.3 CASE式とSUM関数を組み合わせる
      • 17.5.4 上司の問題を解決する
        • 処理をアトミックに行っていないので、数字がずれる可能性がある。
        • 冒頭のエピソードの例ではそれほど厳密でなくてよいだろうから分割処理でも大丈夫だろう。
      • 17.5.5 SQLを用いたSQLの自動的な記述
        • 囲み 複数のUPDATEステートメント生成
          SQLの1行目の末尾のカンマが抜けている
  • 18章 インプリシットカラム(暗黙の列)
    • 18.1 目的:タイプ数を減らす
    • 18.2 アンチパターン:ショートカットの罠に陥る
      • 18.2.1 リファクタリングにおける問題
      • 18.2.2 隠れた代償
      • 18.2.3 求めなければ得られない
    • 18.3 アンチパターンの見つけ方
    • 18.4 アンチパターンを用いてもよい場合
    • 18.5 解決策:列名を明示的に指定する
      • 18.5.1 誤りの防止
      • 18.5.2 それは多分、必要ない(YAGNI:You Ain’t Gonna Need It)
      • 18.5.3 ワイルドカードを使えない局面はいずれ訪れる

「SQLアンチパターン」第20回 (1/24)

Posted on by 0 comment

参加者 沼田(読み手)、今井、青木(記)

範囲 pp.181-192

III部 クエリのアンチパターン

  • 16章 プアマンズ・サーチエンジン(貧者のサーチエンジン)
    • 16.5 解決策:適切なツールを使用する
      • 16.5.7 サードパーティーのサーチエンジン (p.181 spinx.confから)
        • search -b “crash -save”の-bは Boolean マッチングモードにするオプション。
        • p.183 l.8 誤植:「検索対象になりる可能性」→「検索対象になり得る可能性」
        • 検索対象が日本語の場合は、わかち書きが必要です。
  • 17章 スパゲッティクエリ
    • 17.1 目的:SQLクエリの数を減らす
    • 17.2 アンチパターン:複雑な問題をワンステップで解決しようとする
      • 17.2.1 意図に反した結果
      • 17.2.2 さらなる弊害
    • 17.3 アンチパターンの見つけ方
    • 17.4 アンチパターンを用いてもよい場合
    • 17.5 解決策:分割統治を行う
      • 17.5.1 ワンステップずつ

「SQLアンチパターン」第19回 (1/21)

Posted on by 0 comment

参加者 青木(読み手)、今井(記)

範囲 pp.173-181

III部 クエリのアンチパターン

  • 16章 プアマンズ・サーチエンジン(貧者のサーチエンジン)
    • 16.1 目的:全文検索を行う
    • 16.2 アンチパターン:パターンマッチ述語を使用する
    • 16.3 アンチパタンの見つけ方
    • 16.4 アンチパターンを用いてもよい場合
    • 16.5 解決策:適切なツールを使用する
      • 16.5.1 ベンダー拡張
      • 16.5.2 MySQLのフルテキストインデックス
        • p.176 MySQLにこの機能があることは知らなかった。
        • p.176 match-boolean.sql内 ‘IN BOOLEAN MODE’とは何?
          • ここの例にある’+’や’-‘などの演算子を使って論理式の検索式をつかって検索するモード。演算子は’+’, ‘-‘以外にもいろいろある。
          • Booleanフルテキスト検索モードのほかに、Natural laguageフルテキスト検索モードもある。(Ref. MySQL 5.6 Reference Manual 12.9. Full-Text Search Functions)
      • 16.5.3 Oracleでのテキストインデックス
        • p.177 ctxcat-search.sql
          ‘(crash save)’はcrashもsaveも含む行になり、文法としてはあっているのだろうが、他のDBMSの例(crashは含むがsaveは含まない行)と異なる。
        • 他のDBMSも含めて、これらの検索に日本語は使えるのだろうか? だめそうだけど。
          → MySQLはMroongaというMySQL用ストレージエンジンを使えばできるようだ。
      • 16.5.4 Microsoft SQL Serverでの全文検索
        • p.178 create-index.sql
          説明が簡単すぎて例の意味がわからない。’2057’って何?
      • 16.5.5 PostgreSQLでのテキスト検索
      • 16.5.6 SQLiteでの全文検索(FTS)
      • 16.5.7 サードパーティーのサーチエンジン (p.181 spinx.confの前まで)

「SQLアンチパターン」第18回 (1/17)

Posted on by 0 comment

参加者 今井(読み手)、青木、沼田(記)
範囲 pp.162 – 171

III部 クエリのアンチパターン

  • 14章 アンビギュアスグループ(あいまいなグループ)
    • 14.5 解決策:あいまいでない列を使用する
      • 14.5.4 JOINを使用する
      • 14.5.5 他の列に対しても集約関数を実行する
      • 14.5.6 グループごとにすべての値を連結する
  • 15章 ランダムセレクション
    • 15.1 目的:サンプル行をフェッチする
    • 15.2 アンチパターン:データをランダムにソートする
    • 15.3 アンチパターンの見つけ方
      • Random/soln/rand-key-from-list.php
        • PreparedStatementを使用しているが、毎回Statementを生成するコードになっている。
        • INTを指定することでインデックスを確実に使いたいから?
    • 15.4 アンチパターンを用いてもよい場合
    • 15.5 解決策:特定の順番に依存しない
      • 15.5.1 1と最大値の間のランダムなキー値を選択する
      • 15.5.2 欠番の穴の後にあるキー値を選択する
      • 15.5.3 すべてのキー値のリストを受けとり、ランダムに1つを選択する
      • 15.5.4 オフセットを用いてランダムに行を選択する
        • Random/soln/limit-offset.php
          • ROUND()を使用した場合、$offsetに入る値の最大値はBugsテーブルのレコード数となるのでは?
          • ROUND()ではなく、FLOOR()にするべきでは?
          • MySQL5.1で試したところ、OFFSETにレコード数を指定したら該当データなし(Empty set)となりました。
      • 15.5.5 ベンダー依存の解決策

「SQLアンチパターン」第17回 (1/14)

Posted on by 0 comment

参加者 沼田(読み手)、今井、青木(記)

範囲 pp.156-162

III部 クエリのアンチパターン

  • 14章 アンビギュアスグループ(曖昧なグループ)
    • 14.2 アンチパターン:非グループ化列を参照する
      • 14.2.1 単一値の原則(Single-Value Rule)
      • 14.2.2 SQLがクエリの意図を汲んでくれるとは限らない
    • 14.3 アンチパターンの見つけ方
      MySQL5.1のリファレンスマニュアルによるとSQLモードの初期値は空(指定なし)。よってONLY_FULL_GROUP_BYは初期値としては指定されていない。
      http://dev.mysql.com/doc/refman/5.1/ja/server-sql-mode.html
    • 14.4 アンチパターンを用いてもよい場合
    • 14.5 解決策:曖昧でない列を使用する
      • 14.5.1 関数従属性のある列のみにクエリを実行する
      • 14.5.2 相関サブクエリを使用する
      • 14.5.3 導出テーブルを使用する
        derived-table.sqlとderived-table-no-duplicates.sqlではjoinするテーブルとjoin条件が異なっているが、derived-table-no-duplicates.sqlはおそらく間違い。b1とmのjoin条件にはproduct_idも必要なはず。

「SQLアンチパターン」第16回 (1/10)

Posted on by 0 comment

参加者 青木(読み手)、沼田、今井(記)

範囲 pp.146-156

III部 クエリのアンチパターン

  • 13章 フィア・オブ・ジ・アンノウン(恐怖のunknown)
    • 13.2 アンチパターン:NULLを一般値として使う、または一般値をNULLとして使う
      • 13.2.1 式でNULLを扱う
      • 13.2.2 NULLを許容する列の検索
      • 13.2.3 プリペアドステートメントでNULLを扱う
      • 13.2.4 NULLの使用を避ける
    • 13.3 アンチパターンの見つけ方
    • 13.4 アンチパターンを用いてもよい場合
    • 13.5 解決策:NULLを一意な値として使う
      • 13.5.1 スカラー式でのNULL
        • p.151 表13-1
          NULL = NULL は、どちらも”不明な値”という意味でTRUEだと思ってしまいそう。
      • 13.5.2 論理式でのNULL
      • 13.5.3 NULLの検索
        • p.153 l.1
          プリペアドステートメントでNULLを渡すとは、
          IS DISTINCT FROM NULL
          になるという意味か?
          この場合は何らかの値が入っているという条件?
          IS NOT NULL との違いは?
          → NULLもリテラル値もどちらも入る可能性があるときに便利なのでは。
        • 囲み
          昔、osCommerceのconfigでこのようなことがあった。
          (と言いましたが確かめると、NULLと’NULL’ではなくfalseと’false’でした。)
      • 13.5.4 列にNOT NULL制約を宣言する
      • 13.5.5 動的なデフォルト
        • p.154 coalesce.sql
          first_name || COALESCE(' ' || middle_initial || ' ', ' ') || last_name
          は、
          first_name || ' ' || COALESCE(middle_initial || ' ', '') || last_name
          の方がわかりやすいと思う。
  • 14章 アンビギュアスグループ(曖昧なグループ)
    • p.155 表1-2内
      「この行のbug_idが、この行の日付と一致していない」のどちらかの「この行」は、上の表の行のことだろう。
    • 14.1 目的:グループ内で最大値を持つ行を取得する

「SQLアンチパターン」第15回 (1/7)

Posted on by 0 comment

参加者 今井(読み手)、青木、沼田(記)
範囲 pp.134 – 146

II部 データベース物理設計のアンチパターン

  • 12章 インデックスショットガン(闇雲インデックス)
    • 12.3 アンチパターンの見つけ方
      • 囲み 低選択性のインデックス
        MySQL以外では選択性が高いとインデックスの有効性が低下する?

        • 計算式を見ると確かにそうなっている。なぜ?
        • 高くすればいいというわけではないということ?
        • 選択性という言葉の指標が違うということ?
        • 値が分布している方がよい、という点では一緒のことを言っている。
    • 12.4 アンチパターンを用いてもよい場合
    • 12.5 解決策:「MENTOR」の原則に基づいて効果的なインデックス管理を行う
      • 12.5.1 Measure(測定)
      • 12.5.2 Explain(解析)
      • 12.5.3 Nominate(指名)
        • 囲み カバーリングインデックス
          テーブルが大きい場合の影響は?
      • 12.5.4 Test(テスト)
      • 12.5.5 Optimize(最適化)
      • 12.5.6 Rebuild(再構築)

III部 クエリのアンチパターン

  • 13章 フィア・オブ・ジ・アンノウン(恐怖のunknown)
    • 13.1 目的:欠けている値を区別する