2009-03-20 6 views
0

Ich habe eine Tabelle in meiner Datenbank und ich möchte für jede Zeile in meiner Tabelle eine eindeutige ID haben und die Reihen nacheinander benannt haben.SQLite - eine intelligente Möglichkeit, neue Objekte zu entfernen und hinzuzufügen

Zum Beispiel: Ich habe 10 Zeilen, jede hat eine ID - beginnend von 0 bis 9. Wenn ich eine Zeile aus einer Tabelle entfernen, sagen wir - Zeile Nummer 5, tritt ein "Loch". Und danach füge ich mehr Daten hinzu, aber das "Loch" ist immer noch da.

Es ist wichtig für mich, die genaue Anzahl der Zeilen zu kennen und in jeder Zeile Daten zu haben, um beliebig auf meine Tabelle zugreifen zu können.

Es gibt einen Weg in SQLite, es zu tun? Oder muss ich das Entfernen und Hinzufügen von Daten manuell verwalten?

Vielen Dank im Voraus, Ilya. ob Sie

+0

Warum müssen Sie dies tun? Warum ist die Zeilen-ID sequenziell wichtig und notwendig? –

Antwort

3

Ich empfehle dringend, dass Sie Ihr Design überdenken. Meiner Meinung nach fragen Sie sich in Zukunft nach Problemen (z. B. wenn Sie eine andere Tabelle erstellen und Beziehungen zwischen den Tabellen haben möchten).

Wenn Sie die Anzahl der Zeilen wissen wollen, benutzen Sie einfach:

SELECT count(*) FROM table_name; 

Wenn Sie Zeilen in der Reihenfolge der ID zugreifen möchten, definieren gerade dieses Feld PRIMARY KEY-Einschränkung verwenden:

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

und bekommen Reihen BY-Klausel mit ASC oder DESC mit ORDER:

SELECT * FROM table_name ORDER BY id ASC; 

Sqlite erstellt einen Index für die Primärschlüsselfeld, so dass diese Abfrage schnell ist. Ich denke, dass Sie daran interessiert wären, über LIMIT und OFFSET Klauseln zu lesen. Die beste Informationsquelle ist die SQLite documentation.

5

Es kann sich lohnen, in Anbetracht wirklich möchte das machen. Primärschlüssel sollte in der Regel nicht über die Lebensdauer der Zeile ändern, und Sie können immer die Gesamtzahl der Zeilen, indem Sie finden:

SELECT COUNT(*) FROM table_name; 

Die sagte, der folgende Trigger sollte „rollen“ jede ID-Nummer, wenn Ein Löschen erzeugt ein Loch:

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; 

Ich habe dies in einer Beispieldatenbank getestet und es scheint zu funktionieren wie angekündigt. Wenn Sie die folgende Tabelle haben:

id name 
1 First 
2 Second 
3 Third 
4 Fourth 

Und löschen where id = 2, danach wird die Tabelle sein:

id name 
1 First 
2 Third 
3 Fourth 

Dieser Trigger eine lange Zeit in Anspruch nehmen kann und eine sehr schlechte Skalierungseigenschaften (es dauert länger für jede gelöschte Zeile und jede verbleibende Zeile in der Tabelle). Auf meinem Computer dauerte das Löschen von 15 Zeilen am Anfang einer 1000-Zeilen-Tabelle 0,26 Sekunden, aber das wird auf einem iPhone sicherlich länger sein.

+0

+1 obwohl ich zustimme, dass ein Reengineering der Nutzung besser sein könnte, ist dies eine clevere Idee. –

2

Wenn Sie nicht Stephen Jennings sehr clever, aber Performance-tötende Ansatz nehmen möchten, nur etwas anders abfragen. Statt:

SELECT * FROM mytable WHERE id = ? 

Do:

SELECT * FROM mytable ORDER BY id LIMIT 1 OFFSET ? 

Beachten Sie, dass OFFSET Null-basiert, so dass Sie 1 von der Variablen subtrahieren müssen Sie die Indizierung mit.

+0

+1 Ich mag diese Lösung besser, besonders wenn Sie nur eine Zeile gleichzeitig abfragen. –

Verwandte Themen