2009年8月1日土曜日

SQL Server Developpers Edition

アマゾンでみると、2005、2008とも5千円~6千円で買えるのか。。。
Evaluation Editionをダウンロードするのが億劫なので、勉強用に買ってみてもいいのかな?

ExcelのTOCリストの記入

仕事で、
/aaa/bbb/ccc/ddd.txt
/aab/ccd/eef/ggh/iii.txt

というデータをExcelに
/aaa /bbb/ccc ddd.txt
/aab /ccd/eefggh iii.txt

のように張り付ける申請書があった時に、1個ずつ手で打ち込んでいる人がいたので、テキストエディタの正規表現の置換を使って
^(/[^/]*)(/.*)/(.*)$

$1\t$2\t$3
に変換した後にExcelの申請書に張り付ければいいんじゃないの?と提案してみました。
わかってくれるかなぁ?

その後追記、上の人は7月末までの契約でした。何やってんだか。。。


ちなみにこの記事では、TOCとはTable of Contentsの意味でトックリストと読んだときには一覧表という意味で使っています。

SQL Serverのトランザクション分離レベル

ADO.NETで自動トランザクションを使って開発するとデフォルトで、トランザクション分離レベルが'Serializable'となります。
なので、
以下の左のような、タスクごとに一番最後に報告した勤務時間のユーザIDを取得するというSQLを実行した場合、トランザクションを閉じるまで、右のような過去の実績報告を追加するということができません(追加だけでなく、勤務時間表のすべての更新作業(追加、更新、削除)ができないはずです)。



これは、Serializableの動きのためです。
この時点のロック状況は、こんな感じ。


Serializableの特徴であるファントム回避のためキーをレンジでロックしています。
報告日時で適切なインデックスがないためオールレンジロックと同様な結果となります。
なので、insert文のロックは、Waitになっています。


このSQLでは場合は、レンジロックが有効に働くインデックスは掛けるのは不可能だと思います。
なので、Select文を速く終わらせるように工夫するか、nolockを付ける(=ダーティリードを許す)かトランザクション分離レベルをSerializableでなくする(=ファントムを許す)ことをしなければなりません。



これが、Serializableの動きとしては正しいのですが、Oracle開発から来た人にはなかなか分かってもらえない。


ちなみに、分離レベルがRepeatable readであれば右のトランザクション中に左の更新ができました。





オラクル開発から来た人曰く、トランザクション分離レベルをリードコミットスナップショットを使うとよいというが、この変更は、テーブル単位ではなくDB単位に指定するものだし、ADO.NETのデフォルトはSerializableなので、プログラムをいじらなければ何も変わらない気がするし、ADO.NETでREADCOMMITTEDを使っているとDBを変えた瞬間から動きが変わる(ロックしなくなる)のでそれでよいかを検証しなければならないと思う。あんまり都合よくいかないような気がするんだけどなぁ。

2009年7月31日金曜日

パラメタライズドクエリの善し悪し

select文をパラメタライズドクエリで引数を指定して実行するプログラムがあったのだけれど、どうも遅い。プログラム内から動かした場合と、SQLトレースを掛けて抽出したSQL文を手で流した場合で、応答時間が全く違う。

で、いろいろ調べてみたところ、手で流した場合と、プログラムから動かした場合で、SQLの実行計画が違っていた。プログラムから動かすものは、SQLを実行したときに実行計画を作り直さず、前回の実行計画を使うみたい。確かに通常の場合は、実行計画を作る分を端折ることができてヨカッタとなるところだけど、、、
今回パラメタライズドクエリに渡す引数は、開始日、終了日の2つで範囲指定しているのだけれど、範囲が1日と10年では実行計画を変えてほしいのだけれど、変わっていないような動きをする。

結局SQLの末尾にOPTION(RECOMPILE)を付けて毎回SQLをコンパイルさせるようにした。
それと、遅くなった場合に、他の更新処理をブロックしないように、SELECT文で指定されているテーブルに対して、WITH(NOLOCK)ヒントを付けました。

テクシンのメモ

今年の報告論文は、、、内容をVSSと自動ビルドとリリース連動と宣言したので、書くときのいろいろメモ。


本書ではバージョン管理システムを示しプロジェクトでの有用性を示す。

Visual Studio .net親和性

どのようなプロジェクトでも発生するリリースの管理。

他のものとの連携を除き構成管理のみ取り上げる。
プロジェクトのみでなく個人的な運用ツールとしても活用可能。

1.はじめに

2.環境および対象範囲

3.構成管理の概要

4.リリース管理の概要

5.多重管理の回避と改修の競合対応
 ・リリース時期、頻度の違い
 ・要望対応と不具合対応の競合
 ・対象モジュール分け
 
6.リリースミス防止策
 ・リリースミス
   →リリースファイルの更新漏れ
   →ソースファイルのバージョン違い(古すぎる/新しすぎるソース)
 ・防止策
   →ダブルチェック:リリース依頼書(Excel)とソースファイル(VSS)とのマッチングチェック
    VSSの履歴・ソースファイルのバージョン抽出・excelとの申請チェック

7.今後の課題
 改修が競合した時の改修内容の横展。
 同一レーンに入れる粒度。
 レーンを増設、撤去するタイミングの取り決め
 
8.おわりに




あーーーーーどうしても書きたくないーーーーー、構成のイメージが全く思い浮かばないーーーー。めんどいーーーーーーー。

データベースのNULLの扱い

データベースには、決まっていない値という意味でNULLというものがあります。
で、このNULLについては、コッドさん曰く2種類の意味があるとのこと。

例えば、

A.自分の父親の生年月日をNULLとしたとき、
1.自分は孤児で父親がいない場合。
2.父親はいるが、生年月日を思い出せない場合。

B.自分の派遣元会社をNULLとしたとき、
1.そもそも自分は正社員で派遣元会社はナンセンスな場合。
2.派遣元を教える筋合いはないと考えている場合。


でも、現在のRDMSでは2のNULLは扱えるものはありません。すべて1の考え方でしか有りません。
ま、かろうじて安全側に倒れているような気がします。

というのは、例えばA-2.の場合、確かに父親の生年月日があるのでこれを扱おうとした場合、大変なことが起こりそう。こういう状態で、父親の誕生月を月ごとに人数を集計しようとした場合、1件でも「父親の誕生日がわからない」というデータがあると、すべての月の人数集計はUNKNOWNになるべきなのだけれど、そんなことになったら、なにもできなくなりそうだから。

というわけで、2を入れるという考えは全力で避けるようにしなければいけない。さらに1のものも避けることができれば、さらにシンプルに考えられるのだけれど。。。

単体テストの目標数について

単体のテストケースを見たところ、何かテストケースが不足している感じがしたので、プログラマに確認したところ、以下のような考え方でした。。
・テストケースを挙げれば無数に挙げられるが、それだとテストが終わらない
・コードステップ数から割り出した目標テストケース数を目標に設定している

うーん、コードステップ数と関係がない画面の表示位置やタブ順などがテストケースの3割ぐらい占めているのに、、、これを差し引かないで全体のテストケース数と目標テストケース数と比べるのは、何か不思議な感じ。それに目標テストケース数は単なる指標であって、理由があれば大幅に越えても仕方がないものだと思うのだけれど。

単体テストの目的は、機能がうまく動くことの確認だけでは不十分で、単体テストで見つけておくべきバグを見つけ潰しておくことで、確かに後半部分は完ぺきにはできないが、それでも今見ているケースは粗すぎるような気がする。

ま、今言っても仕方がないので、単体テストケースレビュは受けていて、特にテストケース不足は指摘されなかったとことを確認して終了。コードレビュもしているとのことなので、たぶん大丈夫なはず。

カスタムラベルコントロールのカスタムプロパティ

前、プログラマさんにこんなカスタムラベルを作ってと依頼しました。
・表示の際に最大表示文字数が指定できる(0を指定した場合は制限なし)
・サニタイズON/OFFを切り替えられる。
・改行を
タグに変換するかを切り替えられる。

で出来上がったものを見てちょっと驚きました。
1つめのプロパティは、int MaxLength:デフォルトは0
2つめのプロパティは、bool RenderHtmlEncode:デフォルトはfalse
3つめのプロパティは、bool RenderNewLine:デフォルトはfalse

もちろん注目は2つめと3つめのプロパティ。
RenderHtmlEncodeのtrue,falseってのは何?trueの場合どんな動きをするの?
RenderNewLineのtrue/falseって、、、

使う人のことをあまり考えてくれない。ま、使うのはプログラマだから毎回コードを見ればいいんだけど、今後、毎回見なきゃいけないのかなぁ。
プロパティ名を工夫するか、値を列挙型を使って示してほしかったところ。