2009-03-20 4 views
0

J'ai une table dans ma base de données et je veux que chaque ligne de ma table ait un identifiant unique et que les lignes soient nommées par la suite. Par exemple: J'ai 10 lignes, chacune a un id - commençant à 0, se terminant par 9. Lorsque je supprime une ligne d'une table, disons - ligne numéro 5, il se produit un "trou". Et après j'ajoute plus de données, mais le "trou" est toujours là.SQLite - une manière intelligente de supprimer et d'ajouter de nouveaux objets

Il est important pour moi de connaître le nombre exact de lignes et d'avoir à chaque ligne des données afin d'accéder arbitrairement à ma table.

Il y a un moyen en sqlite de le faire? Ou dois-je gérer manuellement la suppression et l'ajout de données? Nous vous remercions d'avance, Ilya.

+0

Pourquoi avez-vous besoin de faire cela? Pourquoi l'identification séquentielle est-elle importante et nécessaire? –

Répondre

3

Je vous suggère fortement de repenser votre conception. À mon avis, vous vous demandez des problèmes dans le futur (par exemple si vous créez une autre table et que vous voulez avoir des relations entre les tables).

Si vous voulez connaître le nombre de lignes utiliser simplement:

SELECT count(*) FROM table_name; 

Si vous souhaitez accéder à des lignes dans l'ordre d'id, il suffit de définir ce champ à l'aide contrainte PRIMARY KEY:

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

et à obtenir des lignes en utilisant la clause ORDER BY avec ASC ou DESC:

SELECT * FROM table_name ORDER BY id ASC; 

SQLite crée un index pour la champ clé primaire, donc cette requête est rapide. Je pense que vous seriez intéressé à lire sur les clauses LIMIT et OFFSET. La meilleure source d'information est la SQLite documentation.

5

Il peut être utile d'examiner si vous avez vraiment vouloir le faire. Les clés primaires doivent généralement pas changer par la durée de vie de la ligne, et vous pouvez toujours trouver le nombre total de lignes en exécutant:

SELECT COUNT(*) FROM table_name; 

Cela dit, le déclencheur suivant doit « rouler vers le bas » chaque numéro d'identification à chaque fois une suppression crée un trou:

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; 

J'ai testé cela sur un exemple de base de données et il semble fonctionner comme annoncé. Si vous avez le tableau suivant:

id name 
1 First 
2 Second 
3 Third 
4 Fourth 

et supprimer où id = 2, après la table sera:

id name 
1 First 
2 Third 
3 Fourth 

Ce déclencheur peut prendre beaucoup de temps et a des propriétés très pauvres de mise à l'échelle (il faut plus long pour chaque ligne que vous supprimez et chaque ligne restante dans la table). Sur mon ordinateur, supprimer 15 lignes au début d'une table de 1000 lignes a pris 0,26 secondes, mais ce sera certainement plus long sur un iPhone.

+0

+1 bien que je sois d'accord qu'une réingénierie de l'utilisation pourrait être meilleure, c'est une idée intelligente. –

2

Si vous ne voulez pas adopter l'approche très ingénieuse de Stephen Jennings, mais que vous ne voulez pas perdre en performance, faites une requête un peu différente. Au lieu de:

SELECT * FROM mytable WHERE id = ? 

Do:

SELECT * FROM mytable ORDER BY id LIMIT 1 OFFSET ? 

Notez que OFFSET est basé sur zéro, de sorte que vous devrez peut-être soustraire 1 de la variable que vous êtes l'indexation avec.

+0

+1 J'aime mieux cette solution, surtout si vous ne faites qu'interroger une ligne à la fois. –

Questions connexes