SQlite, Id eines Eintrags

  • 4 Antworten
  • Letztes Antwortdatum
B

Bastczuak

Neues Mitglied
0
Hallo Leute,

eine kurze Frage?

Ich habe bemerkt das beim Löschen eines alten Eintrages und danach Einfügen eines neues Eintrages, dieser Eintrag eine neue ID erhält und nicht die des letzten Eintrages. Im meinem Verständnis ist also die vorhegende Zeile noch vorhanden aber leer, da der neue Eintrag ja eine Zeile weiter eingeschrieben wurde (neue ROWID)!?

Ich habe herausgefunden, dass der SQLite Befehl autoincrement dies bewirkt.

So nun wollte ich fragen, was ist der Vorteil dabei, wo liegt der Zweck bei der Sache?

MFG Basti
 
Zugegeben ich hab die SQLite DB noch nicht benutzt.
Aber da wird glaub ich keine leere Zeile drin sein.
Das ist halt das normale Verhalten von autoincrement ids.

Ansonsten müsste die Datenbank ja immer alle Zeilen durchgene und gucken wo die erste freie ID vorhanden ist.
Wenn du die letzte löscht ist das in der theorie noch einfach.
Aber stell dir vor du löscht 100 zufällige Zeilen.
Wenn die Datenbank jetzt hingeht und die freigewordenen Ids sucht ist die schwer damit beschäftigt.
Deshalb wird einfach hochgezählt dann muss sich die Datenbank nur den letzten Wert merken und kann somit viel effizienter neue Zeilen hinzufügen.
 
Wenn die Max-ID erreicht wurde sucht SQLite aber schon nach den wieder
frei gewordenen RowId's - im Gegensatz zu anderen Datenbanksystemen.
 
Zuletzt bearbeitet von einem Moderator:
  • Danke
Reaktionen: Johan
Das ist ja der Sinn und Zweck einer ID (Identifikation). Bei anderen Datenbank-Systemen ist die eindeutig, wird also immer nur erhöht. Die Gefahr eines Überlaufs ist selbst bei einer 32-Bit-ID fast nicht gegeben, speziell auf einem Mobilgerät. Wenn Du die gleiche ID behalten möchtest, dann musst Du halt UPDATE verwenden.

Aber eigentlich sollte man nicht direkt mit IDs arbeiten in der Art, ich weiß ja die ID des Satzes der den Namen "Mustermann" enthält. Sondern immer den Namen "Mustermann" suchen, daraus die ID ermitteln und mit dieser ID dann in anderen, damit verknüpften Tabellen nach korrespondierenden Datensätzen suchen. Das ist Datenbanktheorie bei relationalen DBMSen.
 
ups, sollte kein danke werden :scared:

stimmt sqlite hat 64bit signed Integer als RowID

An dieser Stelle möchte ich mal auf die spezielle Spalte "_id", welche
für Standard ListenAdapter vom Android-SDK vorgegeben ist, eingehen.

Eine Definition "_id INTEGER PRIMARY autoincrement" bietet sich an.
PRIMARY KEY's sollten nicht für Anwendungsdaten verwendet werden.
Insofern ist das okay.

Mir ist diese Vorgehensweise aber kürzlich auf die Füsse gefallen.

Thema: Datensynchronisation.

Es empfiehlt sich eigene Adapter zu schreiben um nicht auf die Spalte
"_id" angewiesen zu sein und in diesem Zusammenhang "_id" als Primary Key
zu verwenden.

Dadurch kann der Primary Key auf eine oder mehrere Spalten mit Anwendungsdaten gelegt werden. Das ist zwar nicht ganz im Sinn
eines Primary Key, aber ...

Tabelle: daten1|daten2|daten3|syncts|syncaction ( Primary Key: daten1, daten2 )

Synchronisation:
1) ermittle den max syncts aus der tabelle
2) hole alle Datensätze vom Server mit größer max ts in Tabelle "temp"
3) REPLACE INTO <tabelle> (daten1,daten2,daten3,syncts,syncaction) SELECT daten1,daten2,daten3,syncts,syncaction FROM temp
4) DELETE FROM <tabelle> where syncaction = "delete"

Auf Serverseite kann syncaction "insert", "update" oder "delete" erhalten.
Datensätze mit "delete" können zyklisch gelöscht werden, wenn syncts älter als x-Monate ist.

Was für SQLite "REPLACE INTO ... SELECT ..." ist, ist bei MySQL

INSERT INTO ... ON DUPLICATE KEY UPDATE ...

Über eine weitere Spalte syncclient kann eine bidirektionale Synchronisation erreicht werden

Synchronisation:
1) ...
2) hole alle Datensätze vom Server mit größer max ts UND nicht von "mir" (syncclient) sind in Tabelle "temp"
3) ...
4) ...

Soviel zum Thema "Tutorial Listenadapter". Mich ärgert bei Tutorials immer
das weiterführenden Aspekten kaum Beachtung geschenkt wird :(

Es geht auch ohne Primary Key auf Anwendungsdaten. Dann aber muss
auf dem Komfort von "REPLACE INTO " verzichtet werden. Die Logik muss
mit INSERT und UPDATE nachgebildet werden. Es läuft auf irgendwas mit
LEFT JOIN und IS NULL hinaus. Das setzt voraus, das in den Statements
die "Schlüsselspalten" benannt werden müssen !

Die Statements in meinem Beispiel können aber generisch gebaut und somit
die Synchronisation für alle Tabellen der Anwendung in einem Automaten
abgearbeitet werden.

Über eine Funktion "Versionsabgleich" kann der Primay Key dynamisch
gesetzt werden. Die Informationen kommen vom Server ...

Bei soviel Dynamik ist der nächste Schritt ein Entity-Framework und die
"Kosten" relativieren sich ggü. einer Batterie an getColumnIndex() ...

Viel Spass beim Android-Proggen :)
 

Ähnliche Themen

P
Antworten
13
Aufrufe
547
Peter18
P
Zurück
Oben Unten