|
-- 歯抜けの最小値を探す
SELECT MIN(seq + 1) AS gap
FROM SeqTbl
WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl);
という風に書けば探索できます。(元の数値 + 1 がテーブルに存在していないもの = 歯抜け の最小値を取ってきている。)
但し、トラックバック先でも言及されているようにテーブルのデータ量が多ければ多いほどコストが増大してしまうので、大量のデータが入る可能性のあるテーブルはコーディングしたほうがよさそうです。
検証は後日行おうと思います。-- 歯抜けの最小値を探す
SELECT MIN(seq + 1) AS gap
FROM SeqTbl
WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl);
という風に書けば探索できます。(元の数値 + 1 がテーブルに存在していないもの = 歯抜け の最小値を取ってきている。)
但し、トラックバック先でも言及されているようにテーブルのデータ量が多ければ多いほどコストが増大してしまうので、大量のデータが入る可能性のあるテーブルはコーディングしたほうがよさそうです。
検証は後日行おうと思います。
2011/05/21
検証マシンスペック CORE i5 2.4GHz
数万件位のデータの場合、1秒以内で返ってきましたが、2000万件のデータでは結果が返ってくるまでに14秒位かかりました。
この方法だと空き番の離れ具合は関係ないので、データ件数が増えない限りかかる時間は変わらないです。
それと、この方法だと最小番号を元に空き番を探すため、最小以前の番号が採番号出来ませんので、厳密に採番する場合は使用しない方が良いです。
(検証中にVSが落ちてしまい、プロジェクトを保存していなかったので再検証が出来ない状態です。。)
コード上で1づつカウントアップしてDBに存在確認をしながら探す方法は、100万件位次の番号と離れている場合は秒単位の問題でないくらい時間がかかるのでお勧めできません。
Readerでデータを回しながらカウントアップしていき、相違が出た時点のカウントを空き番とする方法なら100万件位次の番号と離れている場合でも3秒以内で割り出せたので、現時点ではこの方法が一番良いような気がします。
(最終存在確認はした方が良いと思います。)
列番 | キー値 | カウント
1 | 4 | 4
2 | 5 | 5
3 | 6 | 6
4 | 8 | 7 ←この時点でキー値 <> カウントなので
5 | 9 | 最近の空き番は「7」
直接は関係ないのですが、SQLSERVERの場合はキー列にIDENTITY属性を設定しておけば自動で採番してくれます。
|