relationale SQLite Datenbank mit drei oder mehr Tabellen

  • 6 Antworten
  • Letztes Antwortdatum
M

Mortar

Neues Mitglied
0
Hallo,

ich beschäftige mich jetzt erst seit einigen Tagen mit SQlite im Zusammenhang mit der Entwicklung einer Android App.
Habe viel gelesen und gegoogelt, konnte mir aber leider nicht selbst helfen, da ich kein passendes Tutorial gefunden habe und mir einzelne Beiträge aus verschiedenen Foren kein klares Bild geliefert haben.

Im Wesentlichen geht es mir um folgendes:

- Ich möchte eine Datenbank mit drei Tabellen (Kunden, Adressen, Bestellungen) anlegen.
- Beim Anlegen eines neuen Kunden soll grundsätzlich eine Beziehung zu einem Adressdatensatz bestehen, evtl. auch direkt zu einer Bestellung.
- Ich möchte entweder eine einzelne Tabelle oder wahlweise beim Aufruf einer Tabelle, die korrespondierenden Datensätze der anderen beiden Tabellen anzeigen lassen.
- Beim Löschen gilt ebenfalls, dass ich neben der Möglichkeit einen einzelnen Datensatz einer Tabelle zu löschen, wahlweise auch die Möglichkeit haben möchte, die korrespondierenden Datensätze der anderen beiden Tabellen zu löschen.

Wie ich grundsätzliche eine SQLite-Datenbank (mit nur einer Tabelle) erstelle, habe ich soweit verstanden und auch schon erfolgreich getestet.

Vielleicht kann mir ja hier jemand einen Link zu einem guten Tutorial geben oder selbst ein ausführliches Codebeispiel schreiben.

Besten Dank schonmal im Voraus!
 
OK, wo ist das Problem?

Du weißt wie man Tabellen anlegt also hast du Punkt 1 schon erledigt.

Punkt 2: Beziehungen: es gibt unter SQLite so eine Beziehung unter den Tabellen herzustellen, nur funktioniert dies nicht verlässlich also sprich du wirst dich darum selbst kümmern müssen. Ist ja kein Problem, du kannst ja beim (erfolgreichen) anlegen auch in den anderen Tabellen einen Eintrag erstellen.

Punkt 3: siehe Punkt 2, eben mit Select anweisungen.

Punkt 4: siehe Punkt 2, halt mit Delete, beachte aber die Reihenfolge des löschen wenn du vom SQLite aus eine beziehung herstellst.
 
Mein Problem beginnt bereits beim Anlegen im Hinblick auf die Verwendung eines Fremdschlüssels mit Referenz-Anweisung und ggf. die Erstellung von Triggern.
Habe da verschiede Beispiele im Netz gefunden, die aber nicht auf Datenbanken mit mehr als zwei Tabellen angelegt und auch sehr unterschiedlich waren und immer wieder als fehleranfällig beschrieben worden sind.

Also:
- Wie muss ich beim Kreieren der Datenbank mit dem Foreign Key umgehen und welche zusätzlichen Spalten (mit INTEGER-Datentyp soweit ich das verstanden habe) muss ich in den Tabellen zusätzlich einfügen?

- Muss ich diese besagten Bezugs-Spalten, die ich ja dann offensichtlich irgendwie als Bezug nutze manuell (also beim Hinzufügen der Daten in der Laufzeit) bestücken oder nutzt man da auch die Syntax AUTOINCREMENT?

In der Praxis stelle ich es mir nämlich nicht besonders anwenderfreundlich vor, wenn der Nutzer in manchen Fällen zusätzlich irgendeine Bezugs-ID oder so etwas in der Art eingeben muss.

- Wo muss ich wie oft welche Trigger einsetzen?

- Und zum Auslesen und Löschen wollte ich auch mal einen konkreten Befehl sehen, der mir zeigt, wie genau ich einen Datensatz aus einer Tabelle ziehe und gleichzeitig die Referenzierten dazu.


Wie gesagt, ein Link zu einem dieses Beispiel behandelnden Tuturial wäre mir sehr hilfreich - oder eben Beispiel-Code von einem der vielen erfahrenen Entwickler hier im Forum.
 
Hi Mortar,

wie ich sehe sind deine Fragen mehr vom Database-Design-Natur als vom "coden" an sich.

Ich hätte eine Verständnisfrage:

Die Tabelle: Adressen --> ist diese als Adressen-Tabelle der Kunden gedacht? Wenn Ja, warum möchtest du diese als Standalone-Tabelle haben? Würde es nicht genügen die Adresse eines Kunden als Attribut in der Tabelle "Kunden" zu führen?

Mir geht es nur ums Verständnis vielleicht kann ich dir weiterhelfen, bin in letzter Zeit sehr viel DB-Designen :(
 
Mortar schrieb:
Habe da verschiede Beispiele im Netz gefunden, die aber nicht auf Datenbanken mit mehr als zwei Tabellen angelegt und auch sehr unterschiedlich waren und immer wieder als fehleranfällig beschrieben worden sind.

Vorweg, vergiss das vorgegebene Foreign Key Zeug von SQLite, mach es am besten selber.

Also bei besagten drei Tabellen, Kunden, Adresse, Bestellung.

Da hat Kunden eine KundenID Spalte, diese Spalte ist ein integer oder je nachdem was du nutzen wirst kann es unter umständen auch ein String sein (hier ein link worauf ich hinaus will: How to generate a random alpha-numeric string in Java - Stack Overflow) (muss aber nicht unbedingt sein)

Also du startest und legst einen Kunden an, wenn du einen Kunden anlegst, legst du im gleichen Atemzug auch eine/mehrere(?) Adressen an, wenn du es zulässt das der Benutzer nur eine Adresse angeben kann/darf/soll, würde sich in der Tabelle Adresse die KundenID wunderbar als Foreign Key anbieten.

Somit steht schonmal das Grundgerüst. Kommen wir zu den Bestellungen, bei den Bestellungen kannst du eine Spalte einfügen in der die KundenID gespeichert wird, um eben dir zu besagten Kunden immer alle Bestellungen anzeigen zu lassen.

Mortar schrieb:
- Wie muss ich beim Kreieren der Datenbank mit dem Foreign Key umgehen und welche zusätzlichen Spalten (mit INTEGER-Datentyp soweit ich das verstanden habe) muss ich in den Tabellen zusätzlich einfügen?

- siehe obigen Post

Mortar schrieb:
- Muss ich diese besagten Bezugs-Spalten, die ich ja dann offensichtlich irgendwie als Bezug nutze manuell (also beim Hinzufügen der Daten in der Laufzeit) bestücken oder nutzt man da auch die Syntax AUTOINCREMENT?

- diese Bezugsspalte befüllst nachdem du einen Kunden angelegt hast, ich denke aber das du für die Tabellen Adressen und Bestellungen auch noch ein Primary Key benötigen wirst (nicht zwingend, aber wir wollen es nicht übertreiben), somit musst du dort auf den Primary Key mit AUTOINCREMENT arbeiten.

Mortar schrieb:
In der Praxis stelle ich es mir nämlich nicht besonders anwenderfreundlich vor, wenn der Nutzer in manchen Fällen zusätzlich irgendeine Bezugs-ID oder so etwas in der Art eingeben muss.

- stimmt, deswegen machst du das ja ;) :)

Mortar schrieb:
- Wo muss ich wie oft welche Trigger einsetzen?

- immer wenn der User einen neuen Kunden/Adresse/Bestellung anlegt, löscht, bearbeitet

Mortar schrieb:
- Und zum Auslesen und Löschen wollte ich auch mal einen konkreten Befehl sehen, der mir zeigt, wie genau ich einen Datensatz aus einer Tabelle ziehe und gleichzeitig die Referenzierten dazu.

Scenario: Kunde hat 3 Adressen, du zeigst ihn diese:
(Achtung: PseudoCode)
Code:
select * from adressen where kundenid = 'givenkundenid'

Dann kannst du ihn diese Adresse(n) anzeigen, nun kann er sich eine Adresse aussuchen und mit löschen fortfahren:

(Achtung: PseudoCode)
Code:
delete from adressen where kundenid = 'givenkundenid' and street = 'givenstreet' //etc.

so in etwa kannst du das machen.
 
Ich hätte eine Verständnisfrage:

Die Tabelle: Adressen --> ist diese als Adressen-Tabelle der Kunden gedacht? Wenn Ja, warum möchtest du diese als Standalone-Tabelle haben? Würde es nicht genügen die Adresse eines Kunden als Attribut in der Tabelle "Kunden" zu führen?
Für einen Kunden sollen auch mehrere Adressen ablegbar sein.
Zudem möchte ich auch andere Adressen in der Datenbank speichern können.


Also du startest und legst einen Kunden an, wenn du einen Kunden anlegst, legst du im gleichen Atemzug auch eine/mehrere(?) Adressen an, wenn du es zulässt das der Benutzer nur eine Adresse angeben kann/darf/soll, würde sich in der Tabelle Adresse die KundenID wunderbar als Foreign Key anbieten.
Wie oben beschrieben, möchte ich eben diese Einschränkung (nur eine Adresse) nicht vornehmen.


Kommen wir zu den Bestellungen, bei den Bestellungen kannst du eine Spalte einfügen in der die KundenID gespeichert wird, um eben dir zu besagten Kunden immer alle Bestellungen anzeigen zu lassen.
Wie funktioniert dieses Speichern? Übernimmt das die Anweisung REFERENCES?


Anbei mal auszugsweise die Tabellen:

Kunden:

  • Kundennummer (oder _id?) INTEGER PRIMARY KEY AUTOINCREMENT
  • Name TEXT
  • ...

Adressen:

  • (_id ?) INTEGER PRIMARY KEY AUTOINCREMENT
  • Strasse TEXT
  • ...

Bestellungen:

  • Bestellnummer (oder _id?) INTEGER PRIMARY KEY AUTOINCREMENT
  • Produktnummer INTEGER
  • ...

Vielleicht kannst du mir ja mal dieses konkrete Beispiel ergänzen, sodass ich sehen kann, wo welche Zusatzspalte mit welchem Datentyp und sonstiger Anweisung stehen muss.
 
Hallo zusammen,

der Beitrag ist schon etwas älter, ich weis aber ich bin gerade auf der Suche nach einem Beispiel, wie ich Tabellenbeziehungen in SQLite erstellen kann über die Seite gestolpert.

Wie ich es jetzt gelesen habe, stellt SQLite zwar Funktionen dafür zur verfügung aber man sollte es nicht verwenden.

Um dein Beispiel aufzugreifen:

Anbei mal auszugsweise die Tabellen:

Kunden:

  • KundenID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT
  • Name VARCHAR(100) NOT NULL UNIQUE
  • ...

Adressen:

  • AdressID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT
  • KundenID INTEGER NOT NULL (Wird verwendet um die Beziehung Kunde -> Adresse herzustellen)
  • Strasse VARCHAR(100) NOT NULL
  • ...

Bestellungen:

  • BestellID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT
  • KundenID INTEGER NOT NULL (Wird verwendet um die Beziehung Kunde -> Adresse herzustellen)
  • Produktnummer INTEGER
  • ...
Dann kannst du folgendes händisch machen (oder über Trigger das ist dann deine Sacht)

Bestellungen zu Kunde XY anzeigen:

SELECT * FROM Kunde, Bestellungen WHERE Kunde.KundenID == Bestellungen.KundenID

Adressen zu Kunde XY anzeigen:

SELECT * FROM Kunde, Adressen WHERE Kunde.KundenID == Adressen .KundenID

Adressen zu Kunde XY speichern:

Zuerst prüfen, ob die Adresse, die gespeichert werden soll bereits zu dem Kunden angelegt ist um doppelte zu vermeiden

INSERT INTO Adressen (KundenID, Straße, Ort, ...) VALUES (@KundenID, @Straße, @Ort, @...)

Wenn ich es richtig verstanden habe, dann ist das mit händisch gemeint.
Sprich die Tabellen an sich haben an sich keine Beziehung untereinander aber über die Spalte KundenID, die in allen Tabellen enthalten ist kannst du dann die Beziehung rein logisch herstellen.

Ist eben viel Arbeit aber es geht.
Wenn du einen neuen Kunden anlegen willst und die Adresse auch eingetragen werden soll dann musst du das eben auch im programm machen

Ala:

public bool createKunde()
{
//prüfen ob alle benötigten parameter vorhanden sind

//prüfen ob kunde bereits angelegt ist

//kunde anlegen

//Auto generierte kundenID holen

//adresse anlegen (mit kundenID)

//bestellung anlegen (mit kundenID)
}


Kunde löschen wäre dann quasi genauso ...

Adressen löschen
Bestellungen löschen
Kunde löschen

Wobei ich das vermeiden würde. Ich an deiner Stelle würde keine Kunden löschen sondern sie nur über eine Tabellenspalte auf inaktiv setzen (Aus gründen der Nachverfolgbarkeit kannst du dann immernoch schauen welche Bestellungen aufgegeben wurden und wohin geliefert wurde ect)
 

Ähnliche Themen

R
Antworten
6
Aufrufe
1.204
swa00
swa00
A
Antworten
11
Aufrufe
519
swa00
swa00
S
Antworten
33
Aufrufe
3.782
Sempervivum
S
Zurück
Oben Unten