Monthly Archives: 12月 2013

「SQLアンチパターン」第14回 (12/26)

Posted on by 0 comment

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

範囲 pp.121-134

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

  • 11章 ファントムファイル(幻のファイル)
    • 11.2 アンチパターン:物理ファイルの使用を必須と思い込む
      • 11.2.1 ファイルの削除時における問題
      • 11.2.2 トランザクション分離の問題
      • 11.2.3 ロールバック時における問題
      • 11.2.4 データベースのバックアップツール使用時における問題
      • 11.2.5 SQLアクセス権限使用時における問題
      • 11.2.6 ファイルはSQLデータ型ではない
    • 11.3 アンチパターンの見つけ方
    • 11.4 アンチパターンを用いてもよい場合
      • 11.4.1 常に2つの設計を検討する
    • 11.5 解決策:必要に応じてBLOB型を採用する
  • 12章 インデックスショットガン(闇雲インデックス)
    • 12.1 目的:パフォーマンスを最適化する
    • 12.2 アンチパターン:闇雲にインデックスを使用する
      • 12.2.1 インデックスをまったく定義しない
      • 12.2.2 インデックスを多く定義し過ぎる
        p.132 4つ目のINDEX(bug_id,date_reported,status)について、bug_idは主キーなので、bug_idが複合INDEXの1つ目にくる複合INDEXは意味がないのでは
      • 12.2.3 インデックスが役にたたないとき
        説明に使われている列last_name、first_nameはp.133ではAccountsテーブルのインデックスとして定義されているが、p.134 l.1のSELECT文はBugsテーブルに発行されている。誤植?

「SQLアンチパターン」第13回 (12/24)

Posted on by 0 comment

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

範囲 pp.111-121

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

  • 10章 サーティワンフレーバー(31のフレーバー)
    • 10.1 目的:列を特定の値に限定する
    • 10.2 アンチパターン:限定する値を列定義で指定する
      • 10.2.1 中身は何だろう
      • 10.2.2 新しいフレーバーの追加
        • p.114 add-enum-value.sql
          ENUMの要素追加ではなく、既存の要素を変更したり削除したり順番を変えたりしたときはどうなるのだろう?
        • p.115 l.3 中程「適切なテストを省略したり、…」の意味するところは?
          • 「適切テストを省略したり、…」の誤植?
          • なぜ省略するのか?
            • DBを止める時間を短くするため?
            • でもここらあたりにはDBを止める話は出てきていない。
      • 10.2.3 昔ながらの味は色褪せない
      • 10.2.4 移植が困難
    • 10.3 アンチパターンの見つけ方
    • 10.4 アンチパターンを用いてもよい場合
      • p.116 相互排他的な2つの値に関して
        • 有効/無効やオン/オフはENUMではなくBooleanにするなぁ。
        • これらの文字列をメニュー表示などそのままアプリで使用したいときはENUMの方が便利かも。
        • ENUMの値に日本語は使用できるの?
    • 10.5 解決策:限定する値をデータで指定する
      • 10.5.1 値セットの取得
      • 10.5.2 参照テーブルの値の更新
      • 10.5.3 廃止された値のサポート
      • 10.5.4 移植が容易
        • p.118
          • 自分たちが作るときは、BugStatusテーブルにid列を持たせて、Bugsからそのidで参照させるようにするだろう。
          • idで参照するとデータ量は減る。
          • idで参照するとstatusの値を知りたいときはテーブル結合が必要になる。
          • status値(文字列)の変更は、id列無しでもp.117にあるように’ON UPDATE CASCADE’をつけておけば、BusgStatusテーブルの値変更だけですむ。
  • 11章 ファントムファイル(幻のファイル)
    • 11.1 目的:画像をはじめとする大容量メディアファイルを格納する
    • 11.2 アンチパターン:物理ファイルの使用を必須と思い込む
      • p.121 create-screenshots-path.sql
        • image_idがp.120の’SERIAL NOT NULL’から’BIGINT UNSIGNED NOT NULL’に変わったのはなぜ?
      • p.121 中程、「大多数のプログラマーの間では、…」に関して
        • 自分たちが設計するときも外部ファイルにしていることが多い。
        • WordPressやKnowledgeTreeも外部ファイルだった。

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

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

I部 データベース論理設計のアンチパターン

  • 8章 メタデータトリブル
    • 8.4 アンチパターンを用いてもよい場合
    • 8.5 解決策:パーティショニングと正規化を行う
      • 8.5.1 水平パーティショニングの使用
      • 8.5.2 垂直パーティショニングの使用
      • 8.5.3 従属テーブルの導入

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

  • 9章 ラウンディングエラー(丸め誤差)
    • 9.1 目的:整数の代わりに小数値を使用する
    • 9.2 アンチパターン:FLOATデータ型を使用する
      • 9.2.1 丸めが避けられない
      • 9.2.2 SQLでのFLOATの使用
        • Rounding-Errors/anti/inexact.sql
          リテラル値を2進にしてから比較したら一致する?
    • 9.3 アンチパターンの見つけ方
    • 9.4 アンチパターンを用いてもよい場合
    • 9.5 解決策:NUMERICデータ型を使用する

「SQLアンチパターン」第11回 (12/16)

Posted on by 0 comment

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

範囲 pp.84-96

I部 データベース論理設計のアンチパターン

  • 7章 マルチカラムアトリビュート(複数列属性)
    • 7.2 アンチパターン:複数の列を定義する
      • 7.2.3 一意性の保証
      • 7.2.4 増加する値の処理
    • 7.3 アンチパターンの見つけ方
    • 7.4 アンチパターンを用いてもよい場合
    • 7.5 解決策:従属テーブルを作成する
  • 8章 メタデータトリブル(メタデータ大増殖)
    • 8.1 目的
    • 8.2 アンチパターン:テーブルや列をコピーする
      • 8.2.1 テーブルの増殖
      • 8.2.2 データの整合性を管理する
        • Metadata-Tribbles/anti/data-integrity.sql
          この例ではdate_reportedはDATE型なので時刻は気にしなくてよいが、日時の範囲指定は、「DATETIMEカラム>=’開始日(yyyy-mm-dd)’ AND DATETIMEカラム<‘終了日の翌日(yyyy-mm-dd)’」のように記述することが多い。こうすると時刻を気にせずに日付で範囲指定ができる。
        • Metadata-Tribbles/anti/check-constraint.sql
          EXTRACTは、日時データから特定の要素を取得する関数。
      • 8.2.3 データの同期
      • 8.2.4 一意性の保証
      • 8.2.5 テーブルをまたいだクエリ実行
      • 8.2.6 メタデータの同期
      • 8.2.7 参照整合性の管理
      • 8.2.8 メタデータトリブル列の特定
    • 8.3 アンチパターンの見つけ方

「SQLアンチパターン」第10回 (12/13)

Posted on by 0 comment

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

範囲 pp.73-84

I部 データベース論理設計のアンチパターン

  • 6章 ポリモーフィック関連
    • 6.4 アンチパターンを用いてもよい場合
      • 6.4.1 ポリモーフィック関連を意識的に選択するとき
        • p.73
          親側テーブルと子側テーブルとは、BugsとCommentsで言うとBugsが親側でCommentsが子側。
    • 6.5 解決策:関連(リレーションシップ)を単純化する
      • 6.5.1 参照を逆にする
      • 6.5.2 交差テーブルの作成
        • p.75 図 6-4
          • この図のCommentsとBugsComments関連のBugs側多重度が0以上になっているが、これではあるCommentから複数のBugに関連をはれてしまう。これでは多対多関連を交差テーブルを挟んで実現した状態。
          • BugsComments側多重度は0~1ではないか。BugsCommentsとFeaturesCommentsのどちらかになるので、0は必要。
          • p.74のBugsCommentsの定義でBugsComments側多重度が0~1の制限をつけるには、comment_idにユニーク制約を付け加えればよい。
          • 複合キーに使われている属性にユニーク制約ってできた?
      • 6.5.3 交差点に交通信号を設置する
        • p.75
          6.5.2であがった上記話題はこの節にかいてありました。
      • 6.5.4 両方の「道」を見る
        • p.76
          reverse-join.sqlの処理は重くないのだろうか。この本は今のところ性能については書いていないようだ。
      • 6.5.5 「道」を合流させる
      • 6.5.6 共通の親テーブルの作成
        • p.78 super-table.sql
          • Bugs, FeatureRequests両方共通の属性をIssuesに定義しないのか? BugsやFeatureRequestsは、「・・・」で省略してあるから、記述を省略しただけ?
            → p.79 中程に定義しない理由の説明があった。
          • Comments バグ
            最後の外部キー定義のあとに’,’が付いているのは間違い。
        • p.80 super-join.sql
          JOINの前にINNERはいらない?
          → この本では今まで付いていたが、結合タイプ省略時は内部結合なのでなくても良い。
  • 7章 マルチカラムアトリビュート(複数列属性)
    • 7.1 目的:複数の値を持つ属性を格納する
    • 7.2 アンチパターン:複数の列を定義する
      • p.82
        Multi-Column/anti/update.sqlの説明がないけど何? p.83に同じSQLがあるからここでは不要?
      • 7.2.1 値の検索
      • 7.2.2 値の追加と削除
      • p.84
        上のSQLはタグ削除のUPDATE。下のSQLはタグ追加のUPDATE。(ファイル名をみるとremove-tag.sql, add-tag.sqlだからすぐわかりましたね。)

「SQLアンチパターン」第9回 (12/10)

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

I部 データベース論理設計のアンチパターン

  • 第5章 EAV(エンティティ・アトリビュート・バリュー)
    • 5.3 アンチパターンの見つけ方
    • 5.4 アンチパターンを用いてもよい場合
    • 5.5 解決策:サブタイプのモデリングを行う
      • 5.5.1 シンブルテーブル継承
      • 5.5.2 具象テーブル継承
      • 5.5.3 クラステーブル継承
      • 5.5.4 半構造化データ
      • 5.5.5 後処理
  • 第6章 ポリモーフィック関連
    • p.68 Polymorphic/intro/nonsense.sqlのSELECT文
      c.issue_typeをテーブル名として使おうとしてるけどそんなことはできない、という例?

    • 6.1 目的:複数の親テーブルを参照する
    • 6.2 アンチパターン:二重目的の外部キーを使用する
      • 6.2.1 ポリモーフィック関連を定義する
      • 6.2.2 ポリモーフィック関連へのクエリ実行
      • 6.2.3 非オブジェクト指向の例
    • 6.3 アンチパターンの見つけ方
      • Polymorphic/recog/commentable.rbのCommentクラスとBugsクラスの定義
        クラス名とテーブル名が一致していないがself.table_nameの宣言はなくてよいの?(FeatureRequestクラスにだけ宣言がある)

「SQLアンチパターン」第8回 (12/6)

Posted on by 0 comment

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

範囲 pp.45-58

I部 データベース論理設計のアンチパターン

  • 4章 キーレスエントリ(外部キー嫌い)
    • 4.2 アンチパターン:外部キー制約を使用しない
      • 4.2.2 ミスを調べなければならない
      • 4.2.3 「私のミスではありません!」
      • 4.2.4 「キャッチ=22」なUPDATE
        BOGUSは、「偽の」とか「いんちきの」という意味の形容詞です。
    • 4.3 アンチパターンの見つけ方
    • 4.4 アンチパターンを用いてもよい場合
    • 4.5 解決策:外部キー制約を宣言する
      • 4.5.1 複数テーブルの変更をサポートする
        「バックアップデータのリストアの際に外部キー制約が問題になるのでは」という話題がでました。mysqldumpではバックアップファイルの先頭で外部キー制約を無効にして、ファイルの末で有効にもどしています。
      • 4.5.2 オーバーヘッド、・・・にはなりません
  • 5章 EAV(エンティティ・アトリビュート・バリュー)
    • 5.1 目的:可変属性をサポートする
    • 5.2 アンチパターン:汎用的な属性テーブルを使用する
      • 5.2.1 属性を取得するにはどうするか
      • 5.2.2 データ整合性をどう保つか
        COALESCE関数は引数のうちNULLでない最初の引数を返す関数です。
      • 5.2.3 行を再構築しなければならない

「SQLアンチパターン」第7回 (12/3)

Posted on by 0 comment

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

範囲 pp.36-45

I部 データベース論理設計のアンチパターン

  • 3章 IDリクワイアド(とりあえずID)
    • 3.2 アンチパターン:すべてのテーブルに「id」列を用いる
      • 3.2.1 冗長なキーが作成されてしまう
      • 3.2.2 重複行を許可してしまう
      • 3.2.3 キーの意味がわかりにくくなる
        • p.38
          このアンチパターンが示している、考慮なくどのテーブルにも疑似キーのid列つけることはしないというのは賛成だが、列名として’id’を用いないというのはちょっと疑問。user.userIdとか気持ち悪い。
          selectの時に必要であれば、b.id as bug_id などとすれば良いと思う。
      • 3.2.4 USINGを使用する
      • 3.2.5 複合キーは使いにくい
    • 3.3 アンチパターンの見つけ方
    • 3.4 アンチパターンを用いてもよい場合
    • 3.5 解決策:状況に応じて適切に調整する
      • 3.5.1 わかりやすい列名にしよう
        • p.41
          関連があるときは、相手を何らかのロールとして参照するのだから、相手のid列名ではなく役割名を列名にすることが多いと思う。
      • 3.5.2 規約に縛られない
      • 3.5.3 自然キーと複合キーの活用
        • p.42 最下行
          加えて、「規約は、なぜそうするのか意味(理由)を考えよう」と言いたい。いつでも規約に従っていれば良いというわけではないし、なぜそうするのかの問いに理由もわからず「規約に書いてあるから」と答えるのは恥ずかしいと思う。
        • 私たちはオブジェクト指向をベースに考える(考えてしまう)ので、命名や考え方に疑問が出てくるのかもしれない。
  • 4章 キーレスエントリ(外部キー嫌い)
    • 4.1 目的:データベースのアーキテクチャを単純化する
    • 4.2 アンチパターン:外部キー制約を使用しない
      • p.44
        外部キーは使える場合は使うべきだと思う。ただ、実行速度を優先にしなければならない場合もあるし、SQLで許される全ての操作をアプリから行うわけではないので、コード側で実装することもあるのではないか。
    • 4.2.1 完ぺきなコードを前提にしている