# Warenkorb - Realisierung in DB



## Joggal (16. Jun 2015)

Hallo,

Ich möchte gerne einen Warenkorb entwerfen und bräuchte Hilfe dabei, wie die Tabellen genau aussehen sollten. (Relationen etc). 

Also: Benutzer besitzen einen Warenkorb und Benutzer können sich außerdem Motorräder ausleihen, welche dann im Warenkorb abgelegt werden sollen. Es können zudem von jedem Typ mehrere Stück ausgewählt werden.

Ich dachte dabei an folgendes:
Tabellen: Benutzer, Motorrad, Warenkorb, Historie

Benutzer: Beinhaltet Fremdschlüssel zum Warenkorb
Warenkorb: Beinhaltet Fremdschlüssel zu Motorrad und Anzahl der ausgewählten Motorräder
Außerdem bilden beim Warenkorb die Motorrad ID und die Warenkorb ID gemeinsam den Primärschlüssel.

Da ich beim Warenkorb nun das Problem habe, dass ich nicht mehrmals das gleiche Motorrad darin speichern kann, dachte ich an eine Art Historie Tabelle, in welcher diese dann so abgespeichert werden, dass man auch die gleichen Arten hinterlegen kann. (also ein Verlauf der ausgeliehenen Motorräder über bspw. ein Jahr)

Ist mein Ansatz so richtig oder habe ich etwas wichtiges vergessen? 

Bitte um schnelle Antworten


----------



## Tobse (16. Jun 2015)

Ich würde das ganze in Bestellungen aufteilen. Jeder Benutzer hat ab dem Moment, ab dem er etwas in den leeren Warenkorb legt, eine Bestellung. Solange diese Bestellung nicht aufgegeben ist, ist sie sein Warenkorb. Dann hast du ein m:n Verhältnis von Bestellung zu Motorrad; die Anzahl kannst du auch in der m:n Tabelle hinterlegen.

Damit hast du Warenkorb und Bestellungen (und damit Bestellungs-Historie) ein einer Tabelle.


----------



## Joggal (16. Jun 2015)

Hey, danke für die schnelle Antwort.

Das klingt erstmal ganz einleuchtend. 
Wie sieht das jedoch dann in der DB aus, wenn der Benutzer nun die Bestellung tätigt? 

Sprich.. Benutzer legt nun in seinen Warenkorb 4 Motorräder. Diese sind dann in der Warenkorb Tabelle gespeichert. (WID, BID, MID, Anzahl)?

Danach bestätigt der Benutzer die Bestellung, d.h. der Warenkorb geht über in eine Tabelle Bestellungen? mit der Warenkorb ID und Benutzer ID?

Irgendwie denke ich so kompliziert^^


----------



## Tobse (16. Jun 2015)

Richtig, du denkst zu kompliziert  Ich stelle mir das so vor:


```
Tabelle user
|ID   |Name
+-----+-----
|5    |Joggal

Tabelle bestellung
|Spalte     |Beschreibung
+-----------+--------------------
|id         |UNSIGNED INT, PK
+-----------+--------------------
|user_id    |UNSIGNED INT, FK zu user.id
+-----------+--------------------
|bestätigt  |BOOLEAN

Tabelle motorrad
|ID   |Name
+-----+---------
|1    |Aprillia
+-----+---------
|2    |BMW
+-----+---------
|3    |Suzuzki
+-----+---------

Tabelle motorrad_bestellung
|Spalte        |Beschreibung
+--------------+--------------------------------------
|motorrad_id   |UNSIGNED INT, NN, PK, FK zu motorrad.id ODC
+--------------+--------------------------------------
|bestellung_id |UNSIGNED INT, NN, PK, FK zu bestellung_id ODC
+--------------+--------------------------------------
|anzahl        |UNSIGNED INT, NN

1. User Loggt sich ein

bestellung:
|id   |user_id |aufgegeben
+-----+--------|-----------


motorrad_bestellung:
|motorrad_id |bestellung_id |anzahl
+------------+--------------+-------


2. User legt 2 BMW in den Warenkorb

bestellung:
|id   |user_id |aufgegeben
+-----+--------|-----------
|1    |5       |false


motorrad_bestellung:
|motorrad_id |bestellung_id |anzahl
+------------+--------------+-------
|2           |1             |2


3. User legt 1 Suzuki in den Warenkorb

bestellung:
|id   |user_id |aufgegeben
+-----+--------|-----------
|1    |5       |false


motorrad_bestellung:
|motorrad_id |bestellung_id |anzahl
+------------+--------------+-------
|2           |1             |2
|3           |1             |1

3. User bestellt

bestellung:
|id   |user_id |aufgegeben
+-----+--------|-----------
|1    |5       |true
```

Da musst du natürlich noch einige Felder hinzufügen, um Bestelldatum, Bezahlung u.s.w. zu regeln aber im Grunde ist es das.


----------



## Joggal (16. Jun 2015)

Ahh ja, so ähnlich habe ich es mir sogar gerade eben noch einmal überlegt 

Danke für die SUPER Hilfe!

Eine Frage hab ich allerdings noch: 
Du hast in deinem Beispiel mit "bestätigt" - "true","false" zum Überprüfen genommen. Wenn die Bestätigung aber nicht true wird, wären ja die Motorräder trotzdem in der nzm_bestellung_motorrad Tabelle. Diese müssten dann programmiertechnisch wieder entfernt werden, oder wie löst man das? Ansonsten stehen da ja Einträge drin, welche keinen Sinn ergeben.

lg


----------



## Tobse (16. Jun 2015)

Joggal hat gesagt.:


> Danke für die SUPER Hilfe!


Keine Ursache 


Solange "aufgegeben" false ist, ist die Bestellung der Aktuelle Warenkorb des Benutzers. Da musst du im Programm sicherstellen, dass es nur einen gibt oder mithilfe eines Timestamps immer den neuesten auswählen.
Wie du richtig erkannst hast, neigen solche "einfacheren" Datenmodelle gern zu etwas Datenmüll. Den kann man über ein Datenbank-Event regelmäßig beseitigen.


----------



## Joggal (16. Jun 2015)

Ah okay! 

Mit "sicherstellen, dass es nur einen gibt" meinst du, dass alle anderen Einträge in der Bestellungen Tabelle herausgelöscht werden müssen? 

lg


----------



## Tobse (16. Jun 2015)

Joggal hat gesagt.:


> Mit "sicherstellen, dass es nur einen gibt" meinst du, dass alle anderen Einträge in der Bestellungen Tabelle herausgelöscht werden müssen?



Nein. Du hast zwei möglichkeiten:

Ein deinem Code nur an genau _*einer Stelle*_ in diese Tabelle schreiben und dabei prüfen, ob bereits ein Eintrag mit false vorhanden ist und dann ggf. updaten.
Oder aber du kannst beim Lesen vom aktuellen Warenkorb immer ein ORDER BY created_at DESC LIMIT 1 anhängen, um sicherzustellen, dass immer nur der Aktuellste ausgelesen wird. Die anderen, "toten", Einträge kannst du dann per Datenbank löschen (siehe Event).


----------



## Joggal (16. Jun 2015)

Okay, danke dir  

Ob ich es verstanden habe, wird sich noch zeigen, aber trotzdem hast du mir ein großes Stück weitergeholfen! 

lg


----------



## Joggal (17. Jun 2015)

Ich hätte da doch noch eine Frage bzgl. des Abspeicherns des Warenkorbes.

Und zwar, wenn ich jetzt ein Motorrad in den Warenkorb lege, lege ich eine Bestellung an, und die nzm Tabelle bekommt den Eintrag mit der Motorrad-ID und der Bestell-ID. 

Ich möchte aber dann ja noch mehere Motorräder in meinen Warenkorb legen. 
Wie kann ich das realisieren, dass dabei nicht eine neue Bestellung angelegt wird, sondern die "aktuelle" Bestell-ID herangezogen wird? 

lg


----------



## Tobse (17. Jun 2015)

Du kannst in der Session die aktuelle Bestell-ID hinterlegen (bzw. beim Login neu aus der DB lesen). Wenn jetzt etwas zum Warenkorb hinzugefügt wird, kannst du direkt darauf zugreiffen.


----------



## Joggal (17. Jun 2015)

Aber die Bestell-ID weiß ich doch bei einem Login nocht nicht?
Diese ändert sich ja jedesmal. Wenn eine Bestellung abgegeben wurde, wird diese Bestellung gespeichert, und bei einer neuen Bestellung eine neue Bestellung in der DB angelegt.

Das bedeutet ja auch, dass innerhalb einer Session mehrere Bestellungen abgegeben werden können.


----------



## Tobse (17. Jun 2015)

Hier mal der pseudo-code, wie ich ihn mir vorstelle:

Beim Login:
1. Ist in der DB eine Bestellung für den User mit _abgegeben = false_?
1.JA.1 Warenkorb = Bestellung
1.JA.2 Session[Warenkorb-Bestellung] = Bestellung
1.NEIN Warenkorb ist leer

Beim Legen eines Aritkels in den Warenkorb:
1. Ist Session[Warenkorb-Bestellung] gesetzt?
1.NEIN.1 Neue Bestellung für den User anlegen, _abgegeben = false_.
1.NEIN.2 Session[Warenkorb-Bestellung] = Neu angelegte Bestellung
2. Aritekl zum Warenkorb Session[Warenkorb-Bestellung] hinzufügen


----------



## Joggal (17. Jun 2015)

ahh okay 

Und in der Session hinterlegst du einfach z.B. session.setAttribute("bestID",id) oder?


----------



## Tobse (17. Jun 2015)

Richtig; fürs erste reicht das völlig aus.


----------



## Joggal (17. Jun 2015)

Okay, wunderbar! 

Wieder einmal danke für deine super Hilfe! 
Gäbe es einen Donate-Button, würde ich den jetzt drücken


----------

