Benötige ich IDs in meiner Datenbank, wenn die Datensätze anhand des Datums identifiziert werden konnten?

17

Ich schreibe meine erste Anwendung für Android und werde die SQLite-Datenbank verwenden, um die Größe so weit wie möglich zu begrenzen. Ich denke jedoch, dass die Frage im Allgemeinen für das Datenbankdesign gilt.

Ich plane, Datensätze mit Text und Erstellungsdatum zu speichern. Die App ist eine eigenständige App, dh, sie wird nicht mit dem Internet verbunden und nur von einem Benutzer aktualisiert. Es besteht also keine Chance, dass mehr als ein Eintrag zu einem bestimmten Datum vorhanden ist.

Benötigt meine Tabelle noch eine ID-Spalte? Wenn ja, welche Vorteile bietet die Verwendung der ID als Datensatzkennung gegenüber dem Datum?

Nieszka
quelle
SQLite erstellt immer eine Ganzzahlspalte für rowid, wenn Sie keine Ganzzahl-PK angeben. Verlassen Sie sich also nicht darauf, keine "ID" -Spalte zu haben, um Platz zu sparen.
Codism
Ich werde hinzufügen, dass in Android einige Klassen Tabellen benötigen, um eine _id-Spalte zu haben. Mehr Infos bei dieser SO Antwort .
Bigstones
5
Wenn Sie das Datum vom Telefon selbst erhalten und der Benutzer in eine frühere Zeitzone fährt (und sein Telefon die Zeit automatisch aktualisiert), besteht eine geringe Wahrscheinlichkeit, dass Sie denselben Zeitstempel mehr als einmal erhalten.
Eugene

Antworten:

22

IMHO wird die Verwendung einer Datumsspalte als Primärschlüssel am besten vermieden.

Ich habe an Systemen gearbeitet, in denen ein Datumsfeld als Primärschlüssel verwendet wird. Wenn Sie mit Datumsfeldern arbeiten, ist das Schreiben von Abfragen zum Zurückziehen von Teilmengen der Daten ein Kinderspiel.

Einige andere Punkte, die Sie möglicherweise berücksichtigen möchten:

Sie denken vielleicht, dass ein Zeitpunkt eindeutig ist, aber das hängt eher von der Granularität der Datumsspalte ab. Sind es Minuten, Sekunden, Millisekunden usw. Können Sie absolut sicher sein, dass Sie niemals eine Verletzung des Primärschlüssels bekommen?

Wenn Sie die Datenbank auf eine andere Plattform migrieren möchten, treten möglicherweise erneut Probleme auf, wenn die Granularität der Datumsdaten zwischen den Plattformen unterschiedlich ist.

Sie müssen natürlich das Ideal mit dem abwägen, mit dem Sie arbeiten müssen. Wenn der Platz wirklich so wichtig ist, kann die Verwendung der Datumsspalte das geringere von zwei Übeln sein. Das ist eine Designentscheidung, die Sie treffen müssen.

Bearbeiten:

Ich möchte darauf hinweisen, dass dies in keiner Weise darauf hindeutet, dass es sich um eine schlechte Entwurfsentscheidung handelt. Nur, dass es Probleme mit der Praktikabilität des betreffenden RDBMS geben könnte.

Robbie Dee
quelle
Es ist schon eine Weile her, dass ich eine SQLite-Abfrage geschrieben habe, aber ist das Filtern nach Datum nicht identisch mit dem Filtern nach ganzen Zahlen, abgesehen von der ausführlicheren Deklaration der Bindungswerte?
DougM
Es ist nur ausführlicher und bei einigen RDBMS tritt das Problem auf, bei dem das Tag- und Monatselement umgekehrt wird, wenn die Datenbank im US-Format eingerichtet wurde.
Robbie Dee
Danke, das sind alles gute Antworten, aber Ihre Erfahrung bei der Arbeit hat den Deal definitiv besiegelt.
Nieszka
Als Nachtrag dazu: Erst heute wurde mir ein Support-Problem für eine Anwendungsüberprüfungstabelle ausgehändigt, bei der aufgrund eines Zeitunterschieds zwischen zwei Clientgeräten eine Verletzung des Primärschlüssels für eine Mitarbeiternummer und ein Zugriffsdatum / eine Zugriffszeit PK angezeigt wird. ..
Robbie Dee
13

Nein, Sie müssen keine ID-Spalte in Ihrem Schema definieren, wenn Sie garantieren können, dass es niemals ein doppeltes Datum gibt.

ABER ...

... das heißt, Sie können es genauso gut verwenden. Das kleine Geheimnis dabei ist, dass SQLite bereits eine eindeutige, automatisch inkrementierende ID für jede Tabelle mit dem Namen ROWID hat. Wenn Sie eine automatisch inkrementierende Ganzzahlspalte in Ihrer Tabelle als PK deklarieren, wird von SQLite keine neue Spalte erstellt, sondern lediglich die vorhandene ROWID-Spalte aliasisiert.

In SQLite hat jede Zeile jeder Tabelle eine 64-Bit-Ganzzahl mit Vorzeichen ROWID. Die ROWID für jede Zeile ist für alle Zeilen in derselben Tabelle eindeutig.

Sie können auf die ROWID einer SQLite-Tabelle zugreifen, indem Sie einen der speziellen Spaltennamen ROWID, ROWID oder OID verwenden. Außer wenn Sie eine gewöhnliche Tabellenspalte zur Verwendung eines dieser speziellen Namen deklarieren, bezieht sich die Verwendung dieses Namens auf die deklarierte Spalte und nicht auf die interne ROWID.

Wenn eine Tabelle eine Spalte vom Typ INTEGER PRIMARY KEY enthält, wird diese Spalte zu einem Alias ​​für die ROWID. Sie können dann auf die ROWID zugreifen, indem Sie einen von vier verschiedenen Namen, die oben beschriebenen ursprünglichen drei Namen oder den Namen verwenden, der in der Spalte INTEGER PRIMARY KEY angegeben ist. Alle diese Namen sind Aliase füreinander und funktionieren in jedem Kontext gleich gut.

http://www.sqlite.org/autoinc.html

Sie sparen also keinen Platz, wenn Sie keine ID-Spalte verwenden, da Sie eine pro Tabelle erhalten, ob Sie dies möchten oder nicht!

GroßmeisterB
quelle
9

Verwenden Sie ein ID-Feld, wenn eine der folgenden Aussagen zutrifft:

  1. Es ist kein natürlicher Schlüssel vorhanden (das Datum ist nicht eindeutig)
  2. Das Datumsfeld ändert sich häufig
  3. Das Datum ist zum Zeitpunkt der Einfügung möglicherweise nicht bekannt.
  4. Ein mehrspaltiger Bezeichner überschreitet drei Spalten, wodurch Verknüpfungen zu ausführlich werden.

Lesen Sie diese Frage: Gibt es eine kanonische Quelle, die "All-Surrogate" unterstützt?

Bearbeiten:

Da meiner Meinung nach , so scheint es , keine der oben genannten gilt, nicht wahr müssen zu verwenden und ID - Feld, aber Sie können ein , wenn Sie möchten.

Tulains Córdova
quelle
1
+1 ID-Spalten sind ein Schema-Code-Geruch, der darauf hinweist, dass Ihre Daten nicht wirklich zum relationalen Modell passen.
Ross Patterson
10
@ RossPatterson Ich bin nicht so sicher. Ich kann mir eine Reihe von Fällen vorstellen, in denen möglicherweise kein natürlicher Schlüssel vorhanden ist, die Daten aber trotzdem zum relationalen Modell passen. Nur ein Fall, der mir auf den Kopf gestellt wurde: Informationen über lebende Personen speichern. Viele ( nicht alle! ) Länder weisen jedem Bürger eindeutige Identifikatoren zu. Dies bedeutet jedoch nicht, dass die Verwendung dieser Identifikatoren angemessen oder sogar möglich ist (sie sind möglicherweise zum Zeitpunkt der Datensatzerstellung nicht bekannt, werden möglicherweise nicht zugewiesen oder werden nicht verwendet) kann zB durch geltende Vorschriften verboten sein). Bedeutet das, dass die Daten nicht zum relationalen Modell passen? Ich glaube nicht
ein Lebenslauf
Und es gibt die kleine komische Tatsache, dass die Polizei (usw.) bei so eindeutigen Kennungen manchmal Duplikate für ihre gefälschten Ausweise verwendet. Und wenn es nicht beabsichtigt ist, wird ein Schreibfehler auf jeden Fall für Doppelspurigkeit sorgen.
user470365
4
Unabhängig davon, ob es in Oracle integriert ist oder als echte Spalte hinzugefügt wurde, sind sie sehr nützlich. Als jemand, der auf beiden Seiten des Zauns war (DBA & Entwickler), ist es viel einfacher, einen Tisch mit einer ID zu deduplizieren, von der Sie garantieren können, dass sie eindeutig ist.
Robbie Dee
1
@ RobbieDee Sie haben Recht. Es ist nicht zum Thema.
Tulains Córdova
2

Denken Sie daran, dass Sie möglicherweise auch die Bedeutung der Spalte "Datum" von created_atnach updated_atoder jede andere Änderung in dieser Richtung ändern möchten , was meiner Meinung nach ein sehr häufiger Fall ist.

In einigen Fällen können Sie durch Hinzufügen einer ID-Spalte flexibler werden, wenn sich Ihr Design ändert.

wlk
quelle
+1 Das Hinzufügen von date_created und date_modified zu Tabellen ist sehr nützlich, um zu verfolgen, wann Zeilen erstellt und aktualisiert wurden. Dies ist Gold wert, wenn Probleme bei der Aktualisierung von Repositorys / Data Warehouses untersucht werden.
Robbie Dee