C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: SQLで最小の空き番号を取得する方法


(過去ログ 10 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■1595 / inTopicNo.1)  SQLで最小の空き番号を取得する方法
  
□投稿者/ シャノン (90回)-(2007/02/28(Wed) 11:57:46)

分類:[データベース全般] 

Oracle 10gです。

お世話になります。

あるテーブルの列に、数値型で連続性のある(1, 2, 3のような)一意なIDが振られています。
このテーブルから末尾でないレコードを削除した後、新しいレコードを追加する際、削除したレコードのIDを再利用したいのですが、一般的な方法はありますでしょうか?

1. 最初に、IDが1, 2, 3, 4, 5というレコードがあり、
2. ID 2 と 4 を削除したことにより 1, 3, 5 となった場合
3. 次にレコードを追加するときは 2, その次は 4, 以降は 6, 7… としたい

ということです。
ループを回して先頭から1件ずつ、そのIDを持つレコードがあるかどうか…と調べていくのは避けたいです。

ぐぐってみたところ、1件だけ
http://seoi.net/sql/num_blankmin.shtml
見つかったのですが、
> データが増加するほど、すごく重い処理になるため注意して下さい。
とありますし、select が5つも登場していて見るからに複雑そうです。
この方法以外に、もっと簡単な方法がありましたらご教示願います。

#こういう「最小の空き番号」って、一般的にやらないものでしょうか?
引用返信 編集キー/
■1598 / inTopicNo.2)  Re[1]: SQLで最小の空き番号を取得する方法
□投稿者/ road_movie (1回)-(2007/02/28(Wed) 12:26:49)
こんにちは
Oracleは分かりませんがこちらはどうですか?

http://codezine.jp/a/article/aid/652.aspx
引用返信 編集キー/
■1601 / inTopicNo.3)  Re[2]: SQLで最小の空き番号を取得する方法
□投稿者/ シャノン (91回)-(2007/02/28(Wed) 12:53:14)
2007/02/28(Wed) 12:54:33 編集(投稿者)
No1598 (road_movie さん) に返信

ありがとうございます。

> こんにちは
> Oracleは分かりませんがこちらはどうですか?
> 
> http://codezine.jp/a/article/aid/652.aspx

うわ、すごいシンプルですねぇ。

自分でもさらに探して、
http://www.accessclub.jp/bbs/0115/beginers39524.html
というのを見つけました。

で、
「外部結合して NULL かどうか見るくらいなら、EXISTS 使うべきだろう」
ということで、以下のような SQL にたどり着きました。

教えていただいた codezine の例も、EXISTS の代わりに IN を使っているだけで、本質的には同じですね。

SELECT
	NVL( MIN( 番号 ) + 1, 1 )
FROM
	(
		SELECT
			番号
		FROM
			テーブル T1
		WHERE
			NOT EXISTS
			(
				SELECT
					*
				FROM
					テーブル T2
				WHERE
					T1.番号 + 1 = T2.番号
			)
	)

ただ、テーブルが1つならこれでいいですが、実は、要件としては
「2つのテーブルで重複しない整数値」が必要です。
例えば、
テーブルA:1, 3, 7
テーブルB:2, 4, 5
だったら、(AとBのどちらに新しいレコードを作るにせよ)次の値は6、
その次は8である必要があります。
こんなのをこの方法で解こうとすると結合が複雑になりすぎるので、
「削除した番号を持つテーブル」を作るか、「2つのテーブルの
共通部分を1つのテーブルにまとめるよう変更する」かを提案したいと思います。

#そのような要件のないテーブルには、この結果を生かさせて頂きます。

解決済み
引用返信 編集キー/
■1627 / inTopicNo.4)  Re[3]: SQLで最小の空き番号を取得する方法
□投稿者/ corgi (1回)-(2007/03/01(Thu) 01:08:25)
このテーマはOracle機能やSQL機能で解決するよりも業務系実装ロジックで解決したほうが
性能コストや実装コストが合理的におさまるような気がします。

キーを再利用しなければいけない理由が明確になればもう少し議論が進展するのではないでしょうか


たとえばオラクルには「クラスタ表」という機能があります。
キーを再利用しなければいけないシステム仕様があるならば
同時に「クラスタ表」の検討も必要かもしれません

単にキー値の再利用管理が必要ならば
別テーブル作成したほうが(ある意味)スマートと思います

以下のテーブルを作成し
あらかじめ想定するキー範囲で
テーブル作成しておく。

アプりケーションから下記テーブルに対する更新は
STATUS値に対するupdateのみ・・・・みたいな

Create Table キー管理
( KEY number(8),
STATUS char(1)
)


引用返信 編集キー/
■1628 / inTopicNo.5)  Re[3]: SQLで最小の空き番号を取得する方法
□投稿者/ corgi (2回)-(2007/03/01(Thu) 01:20:31)
No1601 (シャノン さん) に返信

SQL性能の議論ではin/not in/existsいずれも対象件数増加に伴いCPUコストが増大しますのでお勧めではないと思います

引用返信 編集キー/
■1631 / inTopicNo.6)  Re[4]: SQLで最小の空き番号を取得する方法
□投稿者/ シャノン (92回)-(2007/03/01(Thu) 09:18:47)
2007/03/01(Thu) 09:19:18 編集(投稿者)

No1627 (corgi さん) に返信
> このテーマはOracle機能やSQL機能で解決するよりも業務系実装ロジックで解決したほうが
> 性能コストや実装コストが合理的におさまるような気がします。

「業務系実装ロジック」とは何でしょう?
現状、SQL で組まないとなれば、C# でのプログラムによる解決となります。

> キーを再利用しなければいけない理由が明確になればもう少し議論が進展するのではないでしょうか

単に、キー空間を節約するためです。
以前はもっと切実な理由があって出てきた問題なのですが、そっちの方は解決して、これだけ残りました。

> たとえばオラクルには「クラスタ表」という機能があります。
> キーを再利用しなければいけないシステム仕様があるならば
> 同時に「クラスタ表」の検討も必要かもしれません

DBの便利な機能は全くと言っていいほど使っていません。
「カーソルって何?」「ストアドって何?」っていうレベルで、基本の4大構文(SELECT、INSERT、UPDATE、DELETE)しか使っていません。
いまさら使うわけにもいきません。

> 単にキー値の再利用管理が必要ならば
> 別テーブル作成したほうが(ある意味)スマートと思います

そうですね。候補の一つに考えています。
解決済み
引用返信 編集キー/
■1791 / inTopicNo.7)  Re[5]: SQLで最小の空き番号を取得する方法
□投稿者/ 明智重蔵 (1回)-(2007/03/06(Tue) 13:12:06)
明智重蔵 さんの Web サイト
http://oraclesqlpuzzle.hp.infoseek.co.jp/2-3-27.html
Lead関数とis not trueを使ってはどうでしょう


わんくま同盟のおっかけ 明智重蔵

解決済み
引用返信 編集キー/
■1792 / inTopicNo.8)  Re[6]: SQLで最小の空き番号を取得する方法
□投稿者/ シャノン (103回)-(2007/03/06(Tue) 13:50:37)
No1791 (明智重蔵 さん) に返信
> http://oraclesqlpuzzle.hp.infoseek.co.jp/2-3-27.html
> Lead関数とis not trueを使ってはどうでしょう

むむ…面白い関数ですね。
しかも LNNVL なんてものまで覚えてしまった。

今回の件は、「SQLで技巧を凝らすより、C#でやってしまえ」に落ち着きそうですが、機会があったら利用させて頂きます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -