2009年7月31日金曜日

データベースの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って、、、

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

2009年7月25日土曜日

SQLパフォーマンス問題発生

検索すると、びっくりするぐらい遅い。ado.netのデフォルトタイムアウト30秒が発生しない方が稀。
みてみると、インデックスが効かないことが原因。
つい最近書いた検索条件がダメだったらしい。
あの記事に追記しておきます。

2009年7月4日土曜日

SQL文で失敗 の続き

前の記事のやつは、SQL SERVER 2005では、APPLYを使えばよさそう。
こんなテーブルがあったとして、
(下線は主キー)
TBL_A(ID,NAME,ADDRESS),
TBL_B(ID,START_DATE,JOB)

SELECT A.NAME, B.JOB_NAME
FROM
TBL_A AS A
OUTER APPLY
(SELECT TOP(1) JOB AS JOB_NAME ,ID FROM TBL_B AS BB
WHERE A.ID=BB.ID ORDER BY START_DATE DESC) AS B

CROSS APPLYだと、左入力のみに発生するデータを検索できないためOUTER APPLYです。

SQLの検索条件メモ

検索SQLのWHERE句:

条件1:
検索条件の指定有無@Aが指定されていなかったら(=NULL)検索条件を指定しない。指定されていたらCOL1と比較する。

WHERE
...
(@A IS NULL OR COL1 = @A)


条件2:
検索条件のAND/OR切替@Aが1の場合COL1=@B AND COL2=@C,@Aが2の場合COL1=B OR COL2=@Cを指定する。

WHERE
...
((@A = 1 AND (COL1 = @B AND COL2 = @C)) OR
(@A = 2 AND (COL1 = @B OR COL2 = @C)))

条件3:
ソート順 @Aが1ならCOL1,COL2 @Aが2なら COL3 降順,COL4

ORDER BY
CASE @A WHEN 1 THEN ROW_NUMBER() OVER (ORDER BY COL1,COL2)
WHEN 2 THEN ROW_NUMBER() OVER (ORDER BY COL3 DESC,COL4)
END

こんなのでうまくいくのかな?




ダメだった。条件1をやると、インデックスを使ってくれない。開発者には、「処理中は固定のものだから速度は遅くならないはず」と答えたのにこのありさま。。。あ~あ、またひとつメッキがはがれた感じ。SQL Server2005はそんなに賢くないのかな?

さらにダメダメでした。
全部だ~め。
理由は、非効率なクエリプランができるためです。で、なんでそうなるかというと、、、最近買ったインサイドSQL Server2005に書いてありました。あの本では、ダメな理由と、代替策として、パラメタライズドクエリを組み立てて実行する方法が紹介されていました。

あ~あ。

2009年7月1日水曜日

インサイドSQL Server2005 3冊目

今回のは、T-SQL編。
「T-SQL Querying」と「T-SQL Programing」からちょっとづつ取って1冊にまとめたとのこと。
どうせなら2冊の翻訳本がほしかったところだけど、この本と同時発売の「プログラミングSQL Server2008」があるところをみると、時間制約のため仕方がなかったのかもね。
ちなみに、今回のは6600円でした。ページ単価でも本の値段でも、前2冊のインサイドSQL Server2005と比べて一番高いです。