SQLWorld を支える技術 
SQLWorld★大阪#27 
2014/10/18 SQLWorld おだ
自己紹介 
織田信亮(おだしんすけ) 
大阪で開発者しています 
SQLWorld の代表です 
http://odashinsuke.hatenablog.com/ 
Twitter:@shinsukeoda
SQLWorld って? 
SQL Server を中心にDB の勉強会やってます 
正規化/モデリング, NoSQL とかもやってます 
最近SQL を書くハンズオンやりはじめました 
提示されたお題に対して、SQL を書いてみる
DB インストールしてないとダメなの? 
DB のインストール必要無しです 
ブラウザがあれば参加出来ます 
やろうと思えば、オンラインでも可 
http://tsqlrunner.azurewebsites.net/
裏で使ってるやつら 
Windows Azure Web Sites 
SQL Database (旧SQL Azure) 
ASP.NET MVC 4 
Knockout.js (JS MVVM FW) 
Signal R (Realtime Web for .NET) 
SQL Server ScriptDom (T-SQL Parser) 
Unity (DI の方ね) 
Dapper (Micro ORM) 
html-query-plan (execution plan to html)
裏で使ってるやつら 
Windows Azure Web Sites 
SQL Database (旧SQL Azure) 
ASP.NET MVC 4 
Knockout.js (JS MVVM FW) 
Signal R (Realtime Web for .NET) 
SQL Server ScriptDom (T-SQL Parser) 
Unity (DI の方ね) 
Dapper (Micro ORM) 
html-query-plan (execution plan to html)
Windows Azure Web Sites 
無料でも使える 
クレカ無し60分体験も可能 
サイトのホスト先 
SCM 経由でデプロイ 
GitHub/BitBucket/DropBox/TFS/サイト 
ローカル…
ASP.NET MVC 4 
一番新しいASP.NET MVC 
Web API も使ってます
Knockout.js 
Binding の用途で利用してます 
回答結果画面で利用 
使いやすいので便利 
他のライブラリに依存しない 
部分的に取り入れることが出来る
Signal R 
流行りの双方向通信を行えるライブラリ 
実行環境(Client 含む)によって、通信方法 
が切り替える 
今回は双方向っていうよりは、Server 
Push メインで使ってます
Unity 
P&P 製のDI コンテナ 
特に必要無かったけど、勉強がてらに 
コード/.config どちらでも設定可能 
コンテナなので、インスタンスのライフサイク 
ル管理も可能 
正直この規模なら要らない
Dapper 
Micro ORM 
クエリの結果とクラスのマッピングだけ 
個人的にはこれ位で調度良い 
EF (Entity Framework) とかちょっと… 
Java でもCommons DB Utils/Seasar 
Doma とか良く使ってる
SQL Database (旧SQL Azure) 
Azure のSQL Server 
Azure Web Sites にも20MB分付いてくる 
SQL Server フル機能は使えないけど、今回 
の用途では無問題! 
IaaS にSQL Server を載せるやつとは違う
何回か開催していると 
問題が…
テーブル名が被ることが出てくる 
スキーマ(Schema) を分けることで解消 
クエリにスキーマ指定させるのイケてない 
select * from [20140805].[テーブル] 
開催回毎にユーザーを作成し「既定のス 
キーマ」を指定する 
アプリ側は同じクエリを投げても、ユー 
ザーによって見るテーブルが変わる
テーブル定義の取得 
T-SQL で取得します 
カタログビュー 
sys.~ 
情報スキーマビュー 
INFORMATION_SCHEMA.~ 
内部的にはカタログビュー使ってます 
やりやすい方を使えば良いです。
余計なことを 
させたくない!
自由にクエリを書けることの弊害 
DROP TABLE されたらどうするん? 
DDL 系の操作 
データの追加/変更/削除 
権限(やロール)の設定で対応 
GRANT SELECT / DENY ~ 
ロールの場合はdb_datareader やカスタ 
ム作成したロール
余計なことを 
させたくない! 
その2
リソースを食い尽くす嫌なやつ 
フロー制御言語を使った嫌がらせ 
WHILE 無限ループ 
WAITFOR 長時間ブロック 
CTE(共通テーブル式) を使った無限再帰 
クエリ 
SELECT なので権限云々では防げない 
例:今から毎日分の日付を延々と返すクエリ 
with [CTE] ( [日付] ) as ( 
select getdate() union all select dateadd(d, 1, [日付]) from [CTE] 
) 
select * from [CTE] option (maxrecursion 0)
SQL Server 側では難しそう…
SQL Server ScriptDom 
.NET から使えるT-SQL のParser / 
Generator 
SQL Server Feature Pack からインス 
トール 
SQL Server 2008 位からあるようです 
2008 当時と2012/2014 では名前空間の 
構成が違うので注意
Parser/Generator 
各バージョン毎のParser/Generator 
80(2000)/90/100/110/120(2014) 
新しい構文は古いParser ではエラーになる 
Azure SQL Database 用はありません! 
Generator である程度は書式整形出来る
Parser を使って… 
複数バッチ/複文をNG 
SELECT でないとNG 
MAX RECURSION を指定してるとNG 
権限では防げないような物でも大体OK!
ScriptDom をどこで使うか 
ビルド時の.sql 検証 
構文エラー/規約違反 
クエリの書式統一 
クエリの動的生成 
使ってみたらわかるけど、結構面倒で非現 
実的…
おまけ 
SQL Database で対応しているか調べる 
Visitor を作ってましたが… 
ドキュメント(MSDN) と実環境とでちょい 
ちょい乖離が… 
進化のスピード早いし、ドキュメントが追 
い付かないのもしゃーない 
結局SQL Database で動かしてみないと判 
らん
SQL Database に投げて確認する 
オブジェクト(テーブルとか) が無くても 
とりあえずクエリ投げてOK 
サポートしてないよってエラーが返ってき 
たら未サポート 
オブジェクトが無いよって返ってきたらサ 
ポートされてる
どのクエリが良いのか比べたい! 
テーブルも多くて3個、データ数も2桁 
インデックスもクラスタ化(PK)のみ 
速度を比較しても… 
比較は難しい感 
あえて可読性くらい?
実行プラン出してみた 
実行プランはXML 
オプション指定すると、クエリで取れる 
SET SHOWPLAN_XML ON 
SET SHOWPLAN_XML ON 
GO 
select * from ~ 
GO 
SET SHOWPLAN_XML OFF
SqlCommand で投げる場合 
GO が使えない 
GO はT-SQL ではない 
SSMS/sqlcmd 等で認識されるコマンド 
Execute を分けて実行 
using (var conn = new SqlConnection(ConnStr)) 
using (var cmd = new SqlCommand(@"SET SHOWPLAN_XML ON", conn)) { 
conn.Open(); 
cmd.ExecuteNonQuery(); 
cmd.CommandText = "select * from [MemTable] where [Id] <= 100"; 
File.WriteAllText("Plan.sqlplan", cmd.ExecuteScalar() as string); 
}
Html-query-plan 
http://code.google.com/p/html-query-plan/ 
XML => XSLT 経由でHTML に変換 
JavaScript + CSS も使ってます 
サンプル通りの使い方でほぼOK 
C# 側はXslCompiledTransform でOK 
実行プランの線が表示されてないのは未調 
査。。
まとめ 
Azure Web Sites + 20MB SQLDB なら 
無料! 
色んなの使って動いてます 
他にも面白そうで使えそうなのあれば教 
えてください 
勉強会で使う問題も募集中!

Sql world を支える技術

Editor's Notes

  • #5 動いてるのを見てみましょう。 ちょちょっとクエリを書いて実行。
  • #7 今日はこの3つをメインにスライド用意しています。 他の聞きたい!ってあればそちらも紹介します。
  • #8 SCM は Software configuration management(ソフトウェア構成管理) サプライチェーンマネジメントとは違うよー
  • #16 スキーマ:.NET でいう 名前空間 みたいな物という認識で OK です。 ログイン 作って Database にスキーマとユーザーを作成。ユーザーはログインとスキーマに紐付け。 ログイン は SQL Database なので SQL Server 認証 マルチテナント 等でも使われてるのかも知れませんね。 全テーブルに 会社コード 持つ or そもそも スキーマ 分ける
  • #18 スキーマ で絞り込んで テーブル定義 を取得しています。
  • #20 権限を絞って対応してます。 DROP TABLE とかされると勉強会に支障をきたすので。 sa でアプリ運用しているところもあったりするんですかね? 権限は、スキーマやテーブル単位だけでなく列単位でも掛けれるので、特定の列のデータは見せたくないみたいなのもやろうと思えば可能。
  • #22 通常の回答では出てこないような、嫌がらせをされる事も考える必要あり! maxrecursion 0 は危険! 通常 100回再帰で打ち切りの所を、ずっと再帰しててもええんやでという設定。
  • #24 2008 では、Interface と Impl とで名前空間が分かれていたので、頑張れば 他ベンダーの SQL に対しての Parser/Generator も実装出来た。 Microsoft.Data.Schema.ScriptDom/Microsoft.Data.Schema.ScriptDom.Sql => Microsoft.SqlServer.TransactSql.ScriptDom 2012 からは、T-SQL 専用になりました。
  • #25 Generator はバージョン間の差が良く分からない。。 Parse&Generator のデモ
  • #27 ビルド時に ORDER BY チェックデモ クエリの生成は結構大変 http://odashinsuke.hatenablog.com/entry/20130224/1361714459 の記事最後見せる
  • #31 参加者からの要望
  • #33 XML をとれましたが、そのまま表示しても普通読めません。 SSMS っぽく表示したいなー。MS製の物は無さそう
  • #34 昔試してた時はちゃんと出てた。 デモ作って動かす。