コペンハーゲンのGR8Conf EU 2013でGroovyServとImproxプラグインを紹介してきた
5/22-24にデンマークはコペンハーゲンで開催されたGR8Conf EU 2013というGroovy系のカンファレンスで、GroovyServとImproxプラグインを紹介してきました。
右の写真はコペンハーゲンの定番がっかり観光スポットの「人魚の像」ですね。 がっかり感が軽減されている一枚を選びました。 まあ、どこの観光地にもがっかりスポットはつきものです。 札幌の時計台にくらべれば人魚はだいぶ良かったんじゃないでしょうか。
GR8Conf EUは今年で5周年だそうです。コペンハーゲンがオリジナルですが、「GR8Conf」ブランドのカンファレンスは別ロケーションでも何度か開かれていて、USは今年も7月にありますしほぼレギュラー化してるようですね。他に覚えているところではオーストラリアでも開催されてました。日本でも開きたいですね。
さて、自分の発表ですが、本日動画が公開され(てしまっ)たので、スライドと動画のリンクを張っておきます。 つたない英語ですがよければご笑覧ください。
- 自分の発表のポータルページ的なもの
- スライド
- 動画
当方の深刻な英語力不足にともない今回は不本意ながら「最初に言い訳」メソッドで乗り切りましたが、やっぱりせっかくやるからには「ネイティブ&インタラクティブ」方式を目指したいですね。 最後、質疑がなくて寂しい感じにみえますが、たぶんみなさん気を遣ってくれた感じで、セッション後に数名の方と技術的な話もしましたからね? *1
他の錚々たるスピーカのみなさんの動画も随時公開されていくはずなので、興味がある方はTwitterで@gr8confをフォローしておくと良いと思います。
そうそう、今度の6/21のJGGUG主催GワークショップZで、G*ワークショップZ Jun 2013 - GR8Conf報告&ライブコーディング&GroovyServ/Improxをやります。 ご興味があれば是非是非ご参加ください。
*1:どちらかというと「お前の英語は悪くない」「問題ないよ」「グレートだったぞ」みたいな慰めにきてくれた人の方が多かったですけど。
GrailsからMirageを使うサンプルがあったので試してみた
Mirageという2-way SQLが利用できる素敵なO/RマッパをGrailsで使ってみたというブログがあったので、サンプルコードを落として試してみました。
developmentモードでMySQL使うようになってたので、H2に変更してrun-appして試してみました。
確かにMirageでDB操作できている!
のですが、更新ボタン2回目を押すとuniqueエラーになるのでおかしいなと思ってみてみたら、insert.sqlファイル内に書いてあるINSERT文でIDがハードコードされてるのでそりゃ2回目は失敗しますね。idを省略して自動払い出しを期待して実行してみると、実行毎にレコードが追加できます。素晴らしい。
という感じで、コードを色々見ていたところ、気になる点が色々あったので、forkして自分好みに修正してみました。 コネクション・データソース・トランザクションまわりのための準備が煩雑だったので、その辺を重点的に頑張ってみました。これ、以外と難しくて一応うまく動いてるようだけどもそんなに自信ないです。たぶん大丈夫だと思うんだけど。 あと、テストもSpockで追加したり、もちろんimproxプラグインも追加したりして、かなり好き放題いじってます。 Grailsのバージョンも最新の2.2.2にあげちゃいました。
コミットログに日本語でゆるいコメントを残してるので何をしていったかはコミットログ参照のこと。コミットログとdiffみたらだいたい何やったか理解できるんじゃないかと。
HibernateのネイティブSQLやGroovy-SQLを使う方法で間に合うことも多いですが、2-way SQLを外部ファイルで指定できるのはSeasarの追っかけ的には嬉しいので、チャンスがあったら使ってみようかなぁ。GrailsConnectionProviderの件とかもあるのでプラグイン化も検討してみようかしら。
参考URL
- 元記事
- オレオレ版サンプル
- とそのコミットログ
- Improxプラグイン
- Mirage
- Spock
- Spockワークショップ
GrailsのGORMにおける各種関連とmappingによる名前変更のサンプル
Grailsのドキュメントを翻訳する上で、英文読んでも何を言ってるか分からないので、サンプル書いて試してみた記録です。
↓ここに反映される予定。
生成されたスキーマはPostgreSQLにて確認してあります。 異なるDBMSなら異なるスキーマになることもあるかも知れません。Hibernateのみぞ知る。
多対1/1対1関連(単方向)
基本
ドメインクラス
class Person { String firstName Address address static mapping = { table 'people' firstName column: 'First_Name' } } class Address { String number String postCode static mapping = { postCode type: 'text' } }
生成されたスキーマ
Table "public.people"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
address_id | bigint | not null
first_name | character varying(255) | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fkc4e2328f2efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
Table "public.address"
Column | Type | Modifiers
-----------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "people" CONSTRAINT "fkc4e2328f2efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
Person上のaddressカラムのマッピングを変更してみる
ドメインクラス
class Person { String firstName Address address static mapping = { table 'people' firstName column: 'First_Name' address column: 'Person_Address_Id' // コレの効果は...? } } class Address { String number String postCode static mapping = { postCode type: 'text' } }
生成されたスキーマ
Table "public.people"
Column | Type | Modifiers
-------------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
person_address_id | bigint | not null <-------- ココが変わった!!!
first_name | character varying(255) | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fkc4e2328fec329d0d" FOREIGN KEY (person_address_id) REFERENCES address(id)
Table "public.address"
Column | Type | Modifiers
-----------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "people" CONSTRAINT "fkc4e2328fec329d0d" FOREIGN KEY (person_address_id) REFERENCES address(id)
多対1/1対1関連(双方向)
基本
ドメインクラス
class Person { String firstName Address address static mapping = { table 'people' firstName column: 'First_Name' } } class Address { String number String postCode static belongsTo = [person:Person] static mapping = { postCode type: 'text' } }
生成されたスキーマ
単方向の場合とスキーマは同じ。
Table "public.people"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
address_id | bigint | not null
first_name | character varying(255) | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fkc4e2328f2efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
Table "public.address"
Column | Type | Modifiers
-----------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Referenced by: TABLE "people" CONSTRAINT "fkc4e2328f2efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
Person上のaddressカラムのマッピングを変更してみる
単方向の場合とスキーマは同じなので、後は...わかりますね?
1対多関連(単方向)
基本
ドメインクラス
class Person { String firstName static hasMany = [addresses: Address] static mapping = { table 'people' firstName column: 'First_Name' } } class Address { String number String postCode static mapping = { postCode type: 'text' } }
生成されたスキーマ
Table "public.people"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "people_address" CONSTRAINT "fk3af1764434f4e10e" FOREIGN KEY (person_addresses_id) REFERENCES people(id)
Table "public.address"
Column | Type | Modifiers
-----------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "people_address" CONSTRAINT "fk3af176442efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
Table "public.people_address"
Column | Type | Modifiers
---------------------+--------+-----------
person_addresses_id | bigint |
address_id | bigint |
Foreign-key constraints:
"fk3af176442efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
"fk3af1764434f4e10e" FOREIGN KEY (person_addresses_id) REFERENCES people(id)
Person上のaddressesカラムのマッピングを変更してみる
ドメインクラス
class Person { String firstName static hasMany = [addresses: Address] static mapping = { table 'people' firstName column: 'First_Name' addresses column: 'Person_Address_Id' // コレの効果は...? } } class Address { String number String postCode static mapping = { postCode type: 'text' } }
生成されたスキーマ
Table "public.people"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not null
Indexes: "people_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "people_address" CONSTRAINT "fk3af17644e3b329fc" FOREIGN KEY (person_address_id) REFERENCES people(id)
Table "public.address"
Column | Type | Modifiers
-----------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "people_address" CONSTRAINT "fk3af176442efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
Table "public.people_address"
Column | Type | Modifiers
-------------------+--------+-----------
person_address_id | bigint | <-------- ココが変わった!!!
address_id | bigint |
Foreign-key constraints:
"fk3af176442efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
"fk3af17644e3b329fc" FOREIGN KEY (person_address_id) REFERENCES people(id)
関連テーブル自体を指定する
ドメインクラス
class Person { String firstName static hasMany = [addresses: Address] static mapping = { table 'people' firstName column: 'First_Name' addresses joinTable: [name: 'Person_Addresses', key: 'Person_Id', column: 'Address_Id'] // コレの効果は...? } } class Address { String number String postCode static mapping = { postCode type: 'text' } }
生成されたスキーマ
Table "public.people"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "person_addresses" CONSTRAINT "fk8aeab389671fd1" FOREIGN KEY (person_id) REFERENCES people(id)
Table "public.address"
Column | Type | Modifiers
-----------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "person_addresses" CONSTRAINT "fk8aeab382efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
Table "public.person_addresses" <-------- ココが変わった!!!
Column | Type | Modifiers
------------+--------+-----------
person_id | bigint | not null <-------- ココが変わった!!!
address_id | bigint |
Foreign-key constraints:
"fk8aeab382efad9e3" FOREIGN KEY (address_id) REFERENCES address(id)
"fk8aeab389671fd1" FOREIGN KEY (person_id) REFERENCES people(id)
1対多関連(双方向)
基本
ドメインクラス
class Person { String firstName static hasMany = [addresses: Address] static mapping = { table 'people' firstName column: 'First_Name' addresses cascade: "all-delete-orphan" } } class Address { String number String postCode static belongsTo = [person:Person] static mapping = { postCode type: 'text' } }
生成されたスキーマ
関連テーブルなしに、子テーブル側に親へのIDを保持するスキーマとなる。 「双方向」であるため、晴れて子から親を参照してもOKになるので、関連テーブルを導入するまでもなく、単に親 のIDを持つスキーマ構造が採用できる、ということと推測するが...。
Table "public.people"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "address" CONSTRAINT "fkbb979bf49671fd1" FOREIGN KEY (person_id) REFERENCES people(id)
Table "public.address"
Column | Type | Modifiers
-----------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
person_id | bigint | not null
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fkbb979bf49671fd1" FOREIGN KEY (person_id) REFERENCES people(id)
Person上のaddressesカラムのマッピングを変更してみる
ドメインクラス
class Person { String firstName static hasMany = [addresses: Address] static mapping = { table 'people' firstName column: 'First_Name' addresses cascade: "all-delete-orphan", column: 'Person_Address_Id' // こっちに書いても効かない(エラーにならず単に無視された) } } class Address { String number String postCode static belongsTo = [person:Person] static mapping = { postCode type: 'text' person column: "my_person_id" // コレの効果は...? } }
生成されたスキーマ
hoge=# \d people Table "public.people"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "address" CONSTRAINT "fkbb979bf4576400fe" FOREIGN KEY (my_person_id) REFERENCES people(id)
hoge=# \d address
Table "public.address"
Column | Type | Modifiers
--------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
number | character varying(255) | not null
my_person_id | bigint | not null <-------- ココが変わった!!!
post_code | text | not null
Indexes:
"address_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fkbb979bf4576400fe" FOREIGN KEY (my_person_id) REFERENCES people(id)
多対多関連(双方向)
基本
ドメインクラス
class Group { String name static hasMany = [people: Person] static mapping = { table 'my_group' // PostgreSQLでは'group'テーブルを作成しようとするとエラーになる } } class Person { String firstName static hasMany = [groups: Group] static belongsTo = Group }
生成されたスキーマ
Table "public.my_group"
Column | Type | Modifiers
---------+------------------------+-----------
id | bigint | not null
version | bigint | not null
name | character varying(255) | not null
Indexes: "my_group_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "my_group_people" CONSTRAINT "fk7525b002f314e043" FOREIGN KEY (group_id) REFERENCES my_group(id)
Table "public.person"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not nullIndexes:
"person_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "my_group_people" CONSTRAINT "fk7525b0029671fd1" FOREIGN KEY (person_id) REFERENCES person(id)
Table "public.my_group_people"
Column | Type | Modifiers
-----------+--------+-----------
group_id | bigint | not null
person_id | bigint | not null
Indexes:
"my_group_people_pkey" PRIMARY KEY, btree (group_id, person_id)
Foreign-key constraints:
"fk7525b0029671fd1" FOREIGN KEY (person_id) REFERENCES person(id)
"fk7525b002f314e043" FOREIGN KEY (group_id) REFERENCES my_group(id)
外部キーカラム名を変更する
ドメインクラス
class Group { String name static hasMany = [people: Person] static mapping = { table 'my_group' people column: 'Group_Person_Id' // コレの効果は...? } } class Person { String firstName static hasMany = [groups: Group] static belongsTo = Group static mapping = { groups column: 'Group_Group_Id' // コレの効果は...? } }
生成されたスキーマ
Table "public.my_group"
Column | Type | Modifiers
---------+------------------------+-----------
id | bigint | not null
version | bigint | not null name | character varying(255) | not null
Indexes:
"my_group_pkey" PRIMARY KEY, btree (id)Referenced by:
TABLE "my_group_people" CONSTRAINT "fk7525b0027e1c21ed" FOREIGN KEY (group_person_id) REFERENCES my_group(id)
Table "public.person"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not null
Indexes:
"person_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "my_group_people" CONSTRAINT "fk7525b00253631627" FOREIGN KEY (group_group_id) REFERENCES person(id)
Table "public.my_group_people"
Column | Type | Modifiers
-----------------+--------+-----------
group_person_id | bigint | not null <-------- ココが変わった!!!
group_group_id | bigint | not null <-------- ココが変わった!!!
Indexes:
"my_group_people_pkey" PRIMARY KEY, btree (group_person_id, group_group_id)
Foreign-key constraints:
"fk7525b00253631627" FOREIGN KEY (group_group_id) REFERENCES person(id)
"fk7525b0027e1c21ed" FOREIGN KEY (group_person_id) REFERENCES my_group(id)
関連テーブル名を指定する
ドメインクラス
class Group { String name static hasMany = [people: Person] static mapping = { table 'my_group' people column: 'Group_Person_Id', joinTable: 'PERSON_GROUP_ASSOCIATIONS' // コレの効果は...? } } class Person { String firstName static hasMany = [groups: Group] static belongsTo = Group static mapping = { groups column: 'Group_Group_Id', joinTable: 'PERSON_GROUP_ASSOCIATIONS' // コレの効果は...? } }
生成されたスキーマ
Table "public.my_group"
Column | Type | Modifiers
---------+------------------------+-----------
id | bigint | not null
version | bigint | not null
name | character varying(255) | not null
Indexes: "my_group_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "person_group_associations" CONSTRAINT "fk9dd6e6fc7e1c21ed" FOREIGN KEY (group_person_id) REFERENCES my_group(id)
Table "public.person"
Column | Type | Modifiers
------------+------------------------+-----------
id | bigint | not null
version | bigint | not null
first_name | character varying(255) | not null
Indexes: "person_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "person_group_associations" CONSTRAINT "fk9dd6e6fc53631627" FOREIGN KEY (group_group_id) REFERENCES person(id)
Table "public.person_group_associations" <-------- ココが変わった!!!
Column | Type | Modifiers
-----------------+--------+-----------
group_group_id | bigint | not null
group_person_id | bigint | not null
Indexes:
"person_group_associations_pkey" PRIMARY KEY, btree (group_person_id, group_group_id)
Foreign-key constraints:
"fk9dd6e6fc53631627" FOREIGN KEY (group_group_id) REFERENCES person(id)
"fk9dd6e6fc7e1c21ed" FOREIGN KEY (group_person_id) REFERENCES my_group(id)
GExcelAPI 0.3 リリースしました #gexcelapi
GExcelAPI 0.3をリリースしました。
Change Log、といえるかどうか
変更点としては、以下の2点。
- POI3.9化
- Java7対応 (thanks to @yamap_55)
これだけ?
はい、これだけです。
でも、Java7対応重要です。ですよね?
オレオレMavenリポジトリの移転
あと、今後の使うときの注意点として大事なのが、オレオレMavenリポジトリの移転です。 今までMavenリポジトリとしてGitHubのrawモードを使った疑似リポジトリを使っていましたが、今回からCloudBeesのリポジトリを使うようにしてみました。 既存の0.1、0.2もなんとなくそっちにコピーしてありますので、ひとまず今後はCloudBeesをお使いください*1。
release (stableバージョン)
https://repository-kobo.forge.cloudbees.com/release
snapshot (SNAPSHOTバージョン)
https://repository-kobo.forge.cloudbees.com/snapshot
ごくシンプルなサンプルコードはこんな感じ:
@GrabResolver(name="kobo", root="https://repository-kobo.forge.cloudbees.com/release")
@Grab("org.jggug.kobo:gexcelapi:0.3")
import org.jggug.kobo.gexcelapi.GExcel
def book = GExcel.open(args[0])
assert book.sheets[0].A1.value == "Sheet1-A1"
機能的に網羅したサンプルコードはテストコードを参照のこと:
CellRange#toHtml()の対応状況?
あと、以前に紹介した実験的機能としてのCellRange#toHtml()は以前の通り実験的機能としての位置づけでそのまま含まれています。 シンプルではないシートの場合にまともに動かないことも多いかもしれませんが、実験的と言うことでご了承ください。 なお、パッチ等は大歓迎です。 というか、Windows上のExcelを使う機会が大変少なくなっている昨今なので、むしろコミッタ募集です。
*1:そのうちまた変わるかもしれませんが
IntelliJ IDEAの細かすぎてわかりづらいGroovyサポート:メソッドシグネチャのホバー表示
メソッドコール部分をホバーするとAPIドキュメントを表示してくれるのはIDEとして普通のことだけど、 Groovyのような言語ではメソッドシグネチャで型を明示指定してないことが良くあります。 そういう場合でも、呼出先で使われるプロパティやメソッドなどを使ってどんなオブジェクトを期待しているか、可能な限りわかりやすく表示してくれる。
と、言葉で書いても何を言ってるかわからないだろうから、例を書くと
def hoge(foo, bar, String baz) {
foo.name = ""
println foo.value
bar.toString()
baz.toString()
}
def zzzz() {
hoge()
}
というメソッドがあるときに、zzzzのhoge()の上でカーソルをホバーしてみると(自分の環境だとCommand押しながらホバーでした)....
String hoge (foo.[name, value], bar.toString(), String baz)
と表示されます。
わかります?
- fooはnameとvalueというプロパティが使われてるので、そういうオブジェクト渡せよ
- barはtoString()メソッドが呼ばれてるので、そういうオブジェクト渡せよ
- bazはString型のインスタンス渡せよ
ということが分かります。
長いメソッドだと色んなプロパティ・メソッドが列挙されすぎてすごいことになるんじゃないか!?と心配になりますが、さすがに3つめあたりで省略記法になるようです。
Object hoge (foo.[name, value, ...], bar.toString(), String baz)
インテリジェイアイデアすごい。
Groovy基礎勉強会でGrailsのリクエスト制御をライブコードリーディングしてきました #GroovyBase
書籍『SQLアンチパターン』 #sqlap
献本御礼。
本書のレビューに参加できて大変光栄であります。
- 作者: Bill Karwin,和田卓人(監訳),和田省二(監訳),児島修
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/01/26
- メディア: 大型本
- クリック: 365回
- この商品を含むブログ (4件) を見る
帯には『「転ばぬ先の杖」を知り、リレーショナルデータベースの進化を学ぶ!』とあって、その通りであるなぁと思いますが、個人的には「転んだ後の鞭(ムチ)」として悶絶しながら読むのが断然お勧めです。
今時のアプリケーションを開発する人はRDBMSを避けて通ることはできないはず*1。そして、今までの開発人生でどれだけのDB技術的負債を積み上げてきたことでしょう。本書では、過去のトラウマを直視させられる粒ぞろいのアンチパターンが取り上げられています。
本書におけるアンチパターンは、以下の形式で記述されています。
「アンチパターン」でトラウマを抉られて悶絶しているところに、「アンチパターンを用いてもよい場合」でフォローが入り救済される、という下げて上げる式のノンストップ・ジェットコースター的なドラマティック読書が楽しめます。
目次から章タイトルだけを並べてみます。
I部 データベース論理設計のアンチパターン
1章 ジェイウォーク(信号無視)
2章 ナイーブツリー(素朴な木)
3章 IDリクワイアド(とりあえずID)
4章 キーレスエントリ(外部キー嫌い)
5章 EAV(エンティティ・アトリビュート・バリュー)
6章 ポリモーフィック関連
7章 マルチカラムアトリビュート(複数列属性)
8章 メタデータトリブル(メタデータ大増殖)
II部 データベース物理設計のアンチパターン
9章 ラウンディングエラー(丸め誤差)
10章 サーティワンフレーバー(31のフレーバー)
11章 ファントムファイル(幻のファイル)
12章 インデックスショットガン(闇雲インデックス)
III部 クエリのアンチパターン
13章 フィア・オブ・ジ・アンノウン(恐怖のunknown)
14章 アンビギュアスグループ(曖昧なグループ)
15章 ランダムセレクション
16章 プアマンズ・サーチエンジン(貧者のサーチエンジン)
17章 スパゲッティクエリ
18章 インプリシットカラム(暗黙の列)
IV部 アプリケーション開発のアンチパターン
19章 リーダブルパスワード(読み取り可能パスワード)
20章 SQLインジェクション
21章 シュードキー・ニートフリーク(疑似キー潔癖症)
22章 シー・ノー・エビル(臭いものに蓋)
23章 ディプロマティック・イミュニティ(外交特権)
24章 マジックビーンズ(魔法の豆)
25章 砂の城
人によってトラウマポイントが当然違ってきますが、個人的には
- 「4章 キーレスエントリ(外部キー嫌い)」
- 「5章 EAV(エンティティ・アトリビュート・バリュー)」
あたりが特に悶絶度が高くて楽しめました。
あと、Grails使いとしては、「3章 IDリクワイアド(とりあえずID)」あたりも味わい深いものがありますね。Ruby on Railsの人たちも必読ではないでしょうか。
今まで読んだSQLノウハウ本の中では、以下の2つと並んでトップ3にランクインです。SQLはまだよくわからないという初学者には、まさに「転ばぬ先の杖」として素敵なガイドとなってくれることは間違いないので、安心して購入しましょう。お勧めです。
達人に学ぶ SQL徹底指南書 (CodeZine BOOKS)
- 作者: ミック
- 出版社/メーカー: 翔泳社
- 発売日: 2008/02/07
- メディア: 単行本(ソフトカバー)
- 購入: 52人 クリック: 978回
- この商品を含むブログ (75件) を見る
- 作者: (株)スターロジック羽生章洋
- 出版社/メーカー: 翔泳社
- 発売日: 2006/04/18
- メディア: 単行本
- 購入: 69人 クリック: 903回
- この商品を含むブログ (119件) を見る
*1:そろそろ「NoSQLだけで十分だ!」と言う人も出てくるかもしれないですが