2009-03-20 13 views
0

データベースにテーブルがあり、テーブルの各行に一意のIDがあり、連続して名前が付けられた行が必要です。SQLite - 新しいオブジェクトを削除して追加するスマートな方法

たとえば、私は10の行を持ち、0から始まり9で終わるIDを持っています。テーブルから行を削除すると、行番号5とすると「ホール」が発生します。その後、データを追加しますが、「穴」はまだあります。

私のテーブルに任意にアクセスするには、正確な行数を知り、すべての行のデータを保持することが重要です。

sqliteには方法がありますか?または、手動でデータの削除と追加を管理する必要がありますか?

ありがとうございます。 Ilya。

+0

なぜこれを行う必要がありますか?行IDが重要で必要なものが連続しているのはなぜですか? –

答えて

3

あなたのデザインを再考することを強くお勧めします。私の意見では、将来別の問題を尋ねています(たとえば、別のテーブルを作成してテーブル間に関係がある場合など)。

あなただけの使用行数を知りたい場合は:あなたは、IDの順序で行にアクセスしたい場合は、単にPRIMARY KEY制約を使用して、このフィールドを定義

SELECT count(*) FROM table_name; 

を:

CREATE TABLE test (
id INTEGER PRIMARY KEY, 
... 
); 

とASCまたはDESCをORDER BY句を使用して行を取得:

SELECT * FROM table_name ORDER BY id ASC; 

SQLiteはのためのインデックスを作成します主キーフィールドであるため、このクエリは高速です。 LIMIT句とOFFSET句について読むことに興味があると思います。 最高の情報源はSQLite documentationです。

5

それは本当にあなたかどうかを検討する価値があるかもしれませんこれをやりたい主キーは、通常、行の寿命を通じて変化すべきではない、とあなたは常に実行して、行の合計数を見つけることができます。

SELECT COUNT(*) FROM table_name; 

述べ、次のトリガーは、「ロールダウン」する必要があり、すべてのID番号をいつでも削除すると穴ができます:

CREATE TRIGGER sequentialize_ids AFTER DELETE ON table_name FOR EACH ROW 
BEGIN 
UPDATE table_name SET id=id-1 WHERE id > OLD.id; 
END; 

私はこれをサンプルデータベースでテストしたところ、広告として動作するようです。あなたは次のテーブルがある場合:

id name 
1 First 
2 Second 
3 Third 
4 Fourth 

を、どこのid = 2削除し、その後テーブルは次のようになります。

id name 
1 First 
2 Third 
3 Fourth 

このトリガーは、それがかかる(時間がかかり、非常に貧弱なスケーリング特性を有することができます削除する行ごとに長く、表の残りの行はそれぞれ長くなります)。私のコンピュータでは、1000行のテーブルの最初に15行を削除するのに0.26秒かかりましたが、これは確かにiPhoneで長くなります。

+0

+1使い方のリエンジニアリングが良いかもしれないと私は同意しますが、これは巧妙な考えです。 –

2

スティーブンジェニングスの非常に巧妙だがパフォーマンスを低下させるアプローチをしたくない場合は、ちょっと違うクエリを実行するだけです。代わりに:

SELECT * FROM mytable WHERE id = ? 

の操作を行います。

SELECT * FROM mytable ORDER BY id LIMIT 1 OFFSET ? 

OFFSETはゼロベースなので、あなたがでインデックスを作成している変数から1を減算する必要があるかもしれません。

+0

+1特に、一度に1つの行だけを照会している場合は、このソリューションがより好きです。 –