本ページはアフィリエイトプログラムによる収益を得ています
Amazon.co.jp ・本 (352ページ) / ISBN・EAN: 9784873115894
作品紹介・あらすじ
みんなの感想まとめ
SQLに関するアンチパターンをテーマにしたこの本は、特に実務でSQLを扱う人々にとって非常に役立つ内容が詰まっています。具体的なシチュエーションとそれに対するアンチパターンが体系的に紹介されており、読...
感想・レビュー・書評
-
ある程度SQLに慣れ親しんだ人だったら「あー、あるある」と思いながら楽しめる本。ありがちなシチュエーションと目的、それに対するアンチパターンという構成で紹介されていて読みやすいし、楽しんで読めると思う。
メタデータトリブルを読んでパーティショニング機能が使えないMySQLはもう使うべきじゃないなーと思った(使ってるけど)。今ざっと読み返していいなと思ったアンチパターンはナイーブツリーかなあ。勉強になった。詳細をみるコメント0件をすべて表示 -
とても素晴らしい本でした。SQLを利用したシステムを作る人にはお勧めしたい本です。具体的にイメージが沸くような形式で書かれているので、このアンチパターンがどういう副作用を生むのかというのを体感することができると思います。
-
現場であるある的な内容(既知の内容とも言う)が思ったより多かったですが、系統的に分けられた本は他に見たことない。
基本的なSQL構文は理解したけどテーブル設計はあまりした事ない人とか、今までなんとなく現場のルールに従ってやってきた人には新しい発見が多いかも。
全体的に読みやすいです。 -
やっぱりパターンとして纏まっていることのすばらしさが改めてわかった一冊。今まで、過去の経験上、避けていた方法が、この本でパターンとして整理されていたおかげで、なぜダメな設計なのかを自分の中で再構築できた気がする。
内容としては、半分は知っている内容、半分は知らない内容なので、自分としての目新しさがちょっと無かったので、その点はちょっと評価が低くなるけど、それはまあしょうがないと思う。
目新しいさを除けば、自分のDB設計の再整理に最適なので、ぜひ他の人にも読んで欲しい一冊 -
【オススメ書籍紹介】『SQLアンチパターン』Bill Karwin
(エンジニア:金子)
「愚者は経験に学び、賢者は歴史に学ぶ」
冒頭にドイツの宰相ビスマルクの格言が引用されています。
本のタイトルに入っている言葉である「アンチパターン」は「べからず集」であり、それを学ぶことにより、自らが失敗をせずとも他者の失敗から学ぶことができると書いています。
第4章で書かれているキーレスエントリ(外部キー嫌い)は、まさに過去に失敗した事のあるパターンでした。
DB側で参照整合性などの制約を厳しく設定した場合、アプリ側の実装で制約に違反をすることは出来なくなるため、時には制約が邪魔に感じることがあります。
しかし制約を外すということは、アプリ側での完璧なコード実装を前提にしており、それなりの代償を支払うことになると意識する必要があります。
この本を読んでいたら、もう少し慎重に検討していたと思います。
その他にも過去の開発経験を思い起こすと頷ける内容がいくつもありました。
本書ではアンチパターンごとに解決すべき目的や解決策、そしてアンチパターンを用いても良い場合の例外についてまで言及しているので、非常に実態に即した内容になっています。
日々開発をして行く中で、どうする事が最善か、道に迷う事があると思いますが、考える際の指針になる本だと思います。
その他にも「インデックスショットガン」(闇雲インデックス)や、「IDリクワイアド」(とりあえずID)など、エンジニアにはピンとくるような秀逸なタイトルも読んでいて面白いです。
エンジニアの方にはぜひオススメしたい一冊です。 -
DBを扱うすべてのエンジニアに読んでおいて欲しい一冊。
基本的な内容も多く順序が関係ないのでわからない箇所は読み飛ばしてでも一通り目を通すことをおすすめします。
アンチパターンというアプローチも面白く、他の分野でも見つける努力をすると面白そうです。バッドノウハウにも似ている。特にアンチパターンの見つけ方は面白いです。誰もが通る失敗があったり、なかったり。
愚者は経験に学び、賢者は歴史に学ぶ、そうです。経験に学ぶほうがみに付きやすいですが、すでにわかってる罠を回避するためにも歴史に学びながら経験に学びたいですね。 -
RDBMS に関わるなら、読むべき必読書。
…まあ、率直に言って、 10 年以上 RDBMS に関わっていれば、「何を今さら…」な内容ではある。あるのだが、それに名前を付け、パターンとしてカタログ化されていることが、とても大切なのだ。
振り返れば、アンチパターンに記載されている失敗をいくつか経験し、眠れぬ夜を過ごしたこともあった。パターンにたどり着くまで、熱い議論を繰り広げたこともある。その時間を劇的に短縮できることの価値は、とても大きい。なにせ、私の 10 年が 10 時間ぐらいで習得できるのだから。…いや、まあ、知識が血となり肉となるには 1 年ぐらいはかかると思うけど…。 (^^; 個人差はあれど、知識を伝承するコストが大きく低減することは間違いなく、その価値は計り知れない。
OR マッパー全盛の現代ではあるが、永続化する手段として RDBMS はまだまだ君臨し続ける。サッカーの高度な戦術が、ボールを止める、パスを出すという基礎の上に成り立っているように、本書の技術はシステム構築のエッセンスとして、とても大切なことなのだ。
ソフトウェア技術に関わるなら、ぜひ、一読を。 -
データベースを「データの入れ物」程度に考えている人にこそ読んで欲しい。私たちが目の前の問題に対して導き出した答えのほとんどがアンチパターンとして紹介されている。
アンチパターンに対しての代替咲くだけでなく、あえてアンチパターンを使ってもよい場合にも触れており、かなり実戦的な内容になっている。 -
2章難し〜と思ったが後半簡単になってく感じ。ネタ切れ?
今どきパスワード暗号化せずに保存なんてやろうとしないとできないだろうなあ、当時はあれなのかもしらんが
ずっと積んでた本消化できてよかった -
データベースに触る機会がある方は必ず読んでほしい一冊です。
-
-
省略
-
DB設計や、SQLの書き方を教えてくれる。
-
SQLに日常的に触れるようになってからあらためて目を通した。
ある程度SQLがわかっていると分かるあるあるネタや、普段の業務でやってしまいがちなアンチパターンと対応策が記載されており学びが多い。 -
アプリケーション開発してるなら必須の知識
-
DB設計・クエリ・アプリ開発におけるSQLアンチパターン集。
アンチパターンの定義、解決策だけでなく、用いても良い場合についても触れている。
25もの例があるので、各フェーズごとに本書を読み返して当てはまるものがないかチェックするようにすると良い。
TDDの和田さん親子が共訳してるのでエモい。 -
かなり勉強になる。RDBもそうだが、SQLを書く際にかなり参考になる。
-
パターンに対する解決策だけでなく、用いても良いパターンがあるのは、選択肢の幅が広がりよかった。
翻訳にあたり追加された25章は要らない。 -
⬜️感想
・「あ、これ弊社のシステムでやってるわ」っていうのがちらほら見られた(爆)
ただ、どうしてもアンチパターンを使用せざるを得ない場合も多い(特にRDB以外のデータモデルを定義するときは、本に載っている解決策を使用できない場合がある)。そういう場合でも、アンチパターンであることと、想定される問題点をきっちり理解した上で使用したい。
データベース設計者には必読の一冊だと思った。kindleじゃなくて紙本も買っちゃおうかな。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
⬜️学び:SQLクエリ設計やテーブル設計の勘所を理解する
・「汎用的な属性」には落とし穴があるぞ!
・属性でメタデータを管理しない
・中間テーブルや従属テーブルで解決できる場面は多い
・インデックス
・外部参照
・そのIDは本当に必要か
・ファイルをDBの中に置くか、外に置くか
・疑似キーの振り直しをしない
⬜️学び:業務内で特に意識すべきアンチパターンを把握する
・カンマ区切りで複数の値を属性に入れるパターン(ジェイウォーク)
→検索性の欠如、更新のしにくさ、バリデーションチェックができない
・同一テーブル内で、自身の親を属性で管理する(ナイーブツリー)
→深い階層のカラムを検索しにくい、ノードの削除がしにくい(外部キー制約があるため)
・サブカテゴリを設定する属性を作る(EAV)
→必須属性を設定できない、データ型を使用できない、参照整合性を強制できない
・同一属性を複数用意する(マルチカラムアトリビュート)
→属性が分かれているため検索しにくい、値の追加削除がしにくい、値のユニーク保証ができない、テーブル設計時に必要な箱の数を知るのは難しい
・テーブルや列を複製して使用する(メタデータドリブル)
→ 必要なタイミングでの複製を忘れるとエラーが発生する、データの一意性の保証がしにくい、テーブルを跨いだクエリ実行がしにくい、列を追加する際に複製した全てのテーブルに行う必要がある
・ENUMで入力値の制限を加える
→ENUMの中身を知るクエリは作るのが難しい、入力可能な値を増やすクエリを作るには現在入力可能値を知る必要がある、入力可能値は削除できない、
-
現実にそぐうように、テーブルを設計する。シンプルなSQLを書く
【感想】
SQLの書き方のアンチパターンだけでなく、テーブルの設計からアンチパターンを記述している。このアプローチは正しい。テーブルの設計が下手だと、SQLも煩雑になる。いろいろな条件を考慮して書かなければならなくなる。読みづらく、分岐が多くなり、メンテコストが上がり、バグが埋め込みやすくなる。
本書では、できる限り分かりやすく、メンテナンスのしやすテーブルを設計するには、どうしたらいいのか、アンチパターン事例を用いて紹介をする。「当たり前だったこと」が、本書では名づけされ、丁寧に何故その設計が良くないかが説明されていた。普段何となく行っている設計業務の、自信がちょっぴり増した。
よいテーブル設計は、オブジェクト指向的である。アンチパターンにあてはまるテーブル設計は、オブジェクト指向的でない。テーブル設計の実力をつけるには、オブジェクト指向について学ぶことも有用であるな、と本書を読んで改めて思った。
【本書を読みながら気になったコト】
目次の構造化がよくできているが、直感的に理解しづらい文章となっていることが惜しい。自分用の理解メモとして下に記す。
■データベース論理設計アンチパターン集
1.ジェイクウォーク(信号無視):複数の値をカンマ区切りで持つ
解決策:交差テーブルを作成する
2.ナイーブツリー(素朴な木):どのノードも常に親のみに依存する
解決策:閉包テーブルを用いる
閉包テーブル…先祖/子孫関係を持つノードの組を格納。1レコードにつき1:1関係を表現。ツリー上の離れた位置地にあるノードも含めてすべてのノードが対象。自分自身を参照する行も追加
3.IDリクワイアド(とりあえずID):すべてのテーブルに「id」列を用いる
解決策:主キーの名前を「id」にしない。分かりやすい名前にする。複合キーを使う
4.キーレスエントリ(外部キー嫌い):外部キー制約を使用しない
解決策:外部キー制約を宣言する
5.EAV(エンティティ・アトリビュート・バリュー):数字や日付を文字列に入れる等、現実と異なる汎用的な属性を利用してしまう
解決策:汎用的にレコードを持つためのテーブルを作らない。扱うデータモデルごとに適切なテーブルを作る。クラステーブルを作る
6.ポリモーフィック関連:1つの外部キーが複数のテーブルと参照関係を持つ→参照制約の作成が不可能
解決策:参照関係を逆にする。交差テーブルを作る
7.マルチカラムアトリビュート(複数列属性):同じ概念の値を、別々の列に格納する
解決策:値を格納する列を1つ持つ従属テーブルを作成する
8.メタデータトリブル(メタデータ大増殖):レコードが多いから、同じオブジェクトを格納するテーブルを複数用意する
解決策:パーティショニングと正規化を行う。常に必要のない値は別のテーブルに分割する(垂直パーティショニング)
→これ、めっちゃ勉強になった。今扱っている業務システムのテーブルは、トランザクションテーブルのカラム数がかなり多い。備考や手形等、実際使っいない項目も多いからだ。
>>論理的には、インストーラーファイルはProductsテーブルの属性であるべきです。しかしこのテーブルに対するほとんどのクエリでは、インストーラーを取得する必要はないはずです。このような、まれにしか使用しない大きなデータをproductsに格納していると、ワイルドカードを用いた全列の取得を頻繁に行う場合に、意図しないパフォーマンス問題が生じることがあります
*水平パーティショニングとは(SQL Serverを基に記載)
https://atmarkit.itmedia.co.jp/ait/articles/0612/21/news118.html
データの範囲ごとに、大量データを複数分割して格納する。パーティションごとに、バックアップやインデックス再構築を行う事が可能。ある範囲に障害が発生しても、別のパーティションはテーブルを操作できる。テーブルの可用性を高めることができる
・パーティションは1つのテーブルにつき1000まで作成が可能
・パーティションの基準となる列は1つである。例えば、売上データであれば、売上日を設定する
・パーティション構成はDBのスキーマに登録する
・パーティション関数で指定するパーティション数と、ファイル数は一致させる必要がある
・どのような基準でテーブルを分割するかは、何かしらの固定値で登録する必要がある。つまり、「100万件ごとにパーティションを分ける」という分割はできない。「2022年12月1日ー2022年12月31日」というような分け方が必要
→時期ごとにデータの分割を自動で行っていく手法として、スライディングウィンドウがある
・テーブルとパーティション構成を紐づければ、テーブルにデータが格納されるたびに、パーティションのルールに基づいて登録が行われるようになる
・スライディングウィンドウを実施するには、同じ定義で、同じ分割列を利用したテーブルが必要となる。例えば、セールステーブルアーカイブ、といった名前のテーブルである
・SQL Server 2017以降のバージョンであれば、常にパーティションが利用できる。それより前のバージョンでは、パーティション機能の利用に制限があった https://docs.microsoft.com/ja-jp/sql/relational-databases/partitions/partitioned-tables-and-indexes?view=sql-server-ver15
■データベース物理設計アンチパターン
9.ラウディングエラー(丸め誤差):少数を扱いたい時に、FLOAT型のような実数を扱う型を宣言する。掛け算を行ううちに誤差が増える
解決策:NUMERICかDECIMAL型を用いて、固定精度の小数点を表す
10.31フレーバー:31の味分列を作ってしまう。限定する値を列定義で指定する。味が増えるたびに列を増やす
解決策:限定する値をデータで指定する
11.ファントムファイル(幻のファイル):物理ファイルを使用して、ファイルパスをテーブルに格納する
解決策:必要に応じてBLOB型を用いる。データベースの外部のリソースは、データベースでは管理できないことに注意しましょう
12.インデックスショットガン:インデックスを全く定義しない。インデックスを多く定義しすぎる。役立たないインデックスを定義する。インデックスを活用しないクエリを実行する
13.恐怖のアンノウン:NULLを一般値として利用する。いろいろな値を混在させない
解決策:NULLを一意な値解いて利用する。NULLをある値と比較するとき、等式も不等式もTRUEを返さないことに注意
14.曖昧なグループ:非グループ化列を参照する。MAX値をとったときに、他の列の値は、MAX値を持つレコードの中の値であるとは限らない
解決策:曖昧でない列を利用する。導出用のサブクエリを使って結合する。外部結合を使って、結合できるかどうかで判断する
15.ランダムセレクション:サンプル行をフェッチするために、データをランダムにソートする→インデックスが効かないため、遅くなる
解決策:特定の順番に依存しない。1と最大値の間のランダムなキー値を指定して結合する。全て―のキー値のリストを受け取り、ランダムに1つ選択する。ベンダー固有の関数を利用する
16.貧者のサーチエンジン:全文検索を行うために、パターンマッチ述語を利用する。→ワイルドカード構文を用いると、インデックスのメリットを得られないため、全ての行のスキャンが必要になる
解決策:ベンダーごとの適切な関数、ツールを利用する。例えば、SQL Serverで全文検索が必要になるのであれば、CONTAINS構文を利用するためのクエリを実行する
17.スパゲッティクエリ:複雑な問題をワンステップで解決しようとする
解決策:分割して書く。UNIONを書く。CASEやSUMを適切に用いる。SELECT文を用いて、UPDATE文を動的に記述して、得られた結果をコピーして、実行すると楽
18.暗黙の列:*を使って列指定をする→意図しない列を取得したり、更新するリスクがある
解決策:明示的に列を指定する
19.リーダブルパスワード:パスワードを平文で格納する
解決策:ソルトをつけてパスワードハッシュを格納する
20.SQLインジェクション:未検証の入力値によって、不正な動作を実施させられる
解決策:プリペアードステートメントを実施する。SQL文字列内に直接入力値を渡さずに、クエリを実行する際に喰えりパラメータとして値を渡すようにする。不正な入力値はコード側でフィルタリングする
21.疑似キー潔癖症:主キーのIDに欠番がでたときに、何らかの形で無理やり埋めようとする
解決策:疑似キーの欠番は埋めない
24.魔法の豆:アクティブレコードを使いすぎ、モデル本来の用途で使用できなくなる。(ハンマーを持っても、釘しか打てない)。実ドメインの動きと乖離する
解決策:モデルがアクティブレコードを持つようにする。ドメインモデルやオブジェクト指向に従って設計を行う
25.砂の城:サービスをリリースするのに、想定されるトラブルや問題を予想しない。準備や調査を実施しない
解決策:色々な打ち手を用意しておく。バックアップを取る、テスト環境を用意する、運用ポリシーを定義する
著者プロフィール
児島修の作品
本棚登録 :
感想 :
