Upload
ke-m-kamekoopa
View
5.020
Download
0
Embed Size (px)
DESCRIPTION
社内勉強会資料
Citation preview
ジェイウォーク
SQLアンチパターンその1 信 号 無 視
ジェイウォーク is
単一列に複数の値を格納するSQLアンチパターン
シナリオ
A「ブログに、共同編集機能付けたいんよ」
B「はい」
A「今一人しか編集できないじゃん?」
B「ですね」
A「複数人がいじれるように出来ない?」
B「考えてみます」
シナリオ
B「今のテーブル定義こんな感じだから」
id title author_id
1 俺のブログ 10000
2 私のブログ 20000
シナリオ
B「要はauthorをn人に出来ればいい訳で」
id title author_id
1 俺のブログ 10000
2 私のブログ 20000
シナリオ
B「こうすればいいか」
id title author_id
1 俺のブログ 10000,10001,10002
2 私のブログ 20000,10001,10002
シナリオ
B「こうすればいいか」
id title author_id
1 俺のブログ 10000,10001,10002
2 私のブログ 20000,10001,10002
信 号 無 視
ジェイウォーク
Bの主張
既存のテーブル定義でそのまま実現可能ですしお手軽ですよね
挿入も文字列連結するだけだし、実装コストも低いですしね。
Bの主張
既存のテーブル定義でそのまま実現可能ですしお手軽ですよね
データの妥当性の担保は?
挿入も文字列連結するだけだし、実装コストも低いですしね。
検索は?更新は?削除は?
ジェイウォーク選択のデメリット
効率的な検索が出来なくなる
あるユーザが編集権を持っているブログは?
あるブログの編集権があるユーザ情報は?
正規表現?
パターンマッチ(like)?
いずれにせよindexが効かなくなる
→ 死
ジェイウォーク選択のデメリット
更新がつらい
あるユーザのみ編集権を削除するには?
参照
アプリ側でsplit
削除IDの検索、リストから削除
再更新
ジェイウォーク選択のデメリット
1,2,3
ジェイウォーク選択のデメリット
1,2,3 1 2 3
split
ジェイウォーク選択のデメリット
1,2,3 1 2 3 1 3
split remove
ジェイウォーク選択のデメリット
1,2,3 1 2 3 1 3 1,2
split remove implode
ジェイウォーク選択のデメリット
1,2,3 1 2 3 1 3 1,2
split remove implode
だるい
ジェイウォーク選択のデメリット
参照整合性の維持もできないですし。
ジェイウォーク選択のデメリット
共同編集者の最大人数は何人ですか?
author_idカラムの定義に依存します!
varchar(128)に保存できる限り保存できます!
idが若い(桁数が少ない)と沢山保存できますが
老番(桁数が多い)だとあまり保存できません!
ジェイウォーク選択のデメリット
まとめ
参照が死ぬ
更新が死ぬ
妥当性検査、参照整合性が死ぬ
仕様変更で死ぬ
B「僕は…どうしたらよかったんだ…」
解決策
交差テーブルを使いましょう
2つのテーブルを参照する外部キーを持つテーブルのこと
blogテーブルとusersテーブルの間にもう一つテーブルを作る
解決策
id title
1 俺のブログ
2 私のブログ
blog_id user_id
1 10000
1 10001
1 10002
2 20000
2 10001
2 10002
id name
10000 太郎
10001 一郎
10002 二郎
20000 n郎
これ
PK
blogs users authors
解決策 : 交差テーブル
参照で死なない
シンプルなクエリ、indexも利用できる
集約関数も利用できる(countとか)
更新で死なない
素直にupdate, insert, deleteするだけ
妥当性検査、参照整合性で死なない
カラムの型、外部キー制約
最大編集人数とかにも変な制約はつかない
アプリで制約するのもblog_idでcountするだけ
解決策 : 交差テーブル
id title
1 俺のブログ
2 私のブログ
blog_id user_id
1 10000
1 10001
1 10002
2 20000
2 10001
2 10002
id name
10000 太郎
10001 一郎
10002 二郎
20000 n郎
blogs users authors
「俺のブログ」の編集者の名前
解決策 : 交差テーブル
id title
1 俺のブログ
2 私のブログ
blog_id user_id
1 10000
1 10001
1 10002
2 20000
2 10001
2 10002
id name
10000 太郎
10001 一郎
10002 二郎
20000 n郎
blogs users authors
「一郎」が編集しているブログ
解決策 : 交差テーブル
id title
1 俺のブログ
2 私のブログ
blog_id user_id
1 10000
1 10001
1 10002
2 20000
2 10001
2 10002
id name
10000 太郎
10001 一郎
10002 二郎
20000 n郎
blogs users authors
「俺のブログ」から「二郎」を外す
シンプル!
ジェイウォーク(信号無視)
jaywalk 【自動】〈話〉
〔交通規則を無視して〕道路を横断する、横断歩道のないところを横切る
◆【語源】jay(不注意な人)から。
交差点(交差テーブル)を避ける所から命名
面倒だからと信号無視をせず、交差点をちゃんと渡りましょう。
アンチパターンを用いていい場合
リストの各要素への個別アクセスが存在しない、かつパフォーマンスの為にあえて非正規化を選択する場合
個別要素へのアクセスがなければ検索性は犠牲にしても問題ない
csvが欲しい等の場合、最初からカンマ区切りにしておいた方が効率が良い
おわり