Datenbank innerhalb einer Datenbank

  • Ich frage mich gerade ob es möglich ist eine Datenbank anzulegen deren Einträge wieder eine Datenbank sind.


    Folgende Situation:
    Es gibt zum einen Rezepte die man in einer Datenbank ablegen möchte. Dies sollen neben normalen String und Zahlen Werten auch Zutaten beinhalten.
    Gesucht ist eine saubere Lösung mit welcher ich einfach auf die Zutaten der Rezepte zugreifen kann und diese gegebenenfalls leicht manipulieren könnte.


    Lösungsansatz:
    Ich habe mich gefragt, ob es nicht am meisten Sinn machen würde, wenn man in einer Spalte in einem Datenbank Eintrag eines Rezepts einen String anlegen würde zutaten.db. Zutaten.db wäre dann der Dateiname der Datenbank welche die Zutaten beinhaltet. Ich fände diese Lösung sauberer als die Zutaten direkt in die Rezept Datenbank zu legen da so jeder Eintrag eines Rezepts immer gleich Aufgebaut wäre bezüglich Spaltenanzahl und deren Inhalt.


    Nun weiss ich aber nicht ob es in SQLite einfacher Wege gibt so etwas zu bewerkstelligen oder was in diesem Bereich "State of the Art" ist. Kann mir jemand mit Erfahrung in dem Bereich mal seine Sicht der Dinge präsentieren?
    Wie wird sowas überlicherweise gemacht? Vor- und Nachteile? Hilfsfunktionen in SQLite?

  • Ich korrigiere dich mal.
    Lösungsansatz: Man nehme drei Tabellen A, B und C. In A werden die Rezepte gespeichert, in B die Zutaten und in C ihre Assoziationen (also zusammenhänge). Nun braucht man weder Zutaten in A speichern, noch Rezepte in B. Man macht einfach drei spalten in C. Spalte 1 ist der Primärschlüssel von C und Spalte 2 und 3 sind dann einfach die jeweiligen Primärschlüssel von A und B.


    Wenn man Rezept x hat wo die Zutaten Apfel, Zitrone und Orange vorkommen, gibt es in C drei Einträge. Dabei sind die Zellen der Spalte Rezept alle 3 gleich, nur der Primärschlüssel in der Spalte der Zutaten wird dann angepasst.

  • Diese Primärschlüssel sind die ids von Datenbankeinträgen oder? Also die jeweils erste Zelle eines Eintrags? Die bleiben ja dann immer gleich wenn ich mich recht erinnere sonst würds ja wohl nicht gehen. Und sind nur innerhalb eines .db Files einzigartig also nicht über die ganze Applikation? Dann müsste ich wenn ich das jetzt richtig verstehe eine Datenbank anlegen database.db und dort drin dann die drei von dir vorgeschlagenen Tables A,B,C und nicht A.db B.db C.db als einzelne Datenbank?

  • Es stellen sich mir noch ein paar fragen.


    Es wäre ja so das z.b. Jede Zutat für ein Rezept ein Attribut bezüglich dessen Menge beinhalten würde. Also hab ich mir gedacht, dass ich die Zutaten tabellarisch Zeile für Zeile in das Zutaten Table einfüge mit den Spalten Name|Stückzahl|Gewicht|Volumen|.


    _id_zutNameStückzahlGewichtVolumen
    1BEER23
    2BUTTER85
    3EGG6



    Das Problem sehe ich dann beim zusammenführen der beiden Tabellen: Rezepte und Zutaten. Ich hab dann ja pro Rezept ein Eintrag also einen Primarykey währedem ich bei den Zutaten Anzahl Zutaten * Primarykey bekommen.
    Wenn ich nun die ganzen Assoziationen in einer dritten Tabelle abbilden möchte dann hab ich ja drei Spalten |_id_Asso|_id_Rez|_id_Zut|.



    _id_Asso_id_Rez_id_Zut
    111
    212
    313
    414


    Was ich daran ein bisschen unsauber finde ist, dass es mehrere Assoziations IDs pro Rezept geben kann. Lässt sich das irgendwie umgehen oder muss ich damit leben? Ist es evtl gar nicht schlimm? Ich kann mir einfach gut vorstellen das die Verarbeitung und der Zugriff mittels Cursor leichter wäre wen man eine einzige _id_Asso besitzt. Aber das ist momentan auch eher nur eine Vermutung.


    Ich hab deswegen noch nach andere Möglichkeiten gesucht aber auch diese erscheinen mir nicht sonderlich besser.
    Eine davon ist in der Zutaten Tabelle einfach pro Zeile immer pro Spalte eine Zutat einfügen, so dass alle Zutaten eines Rezepts auf einer Spalte wären (quasi ein Zeilenvektor bilden).


    _id_ZutZutatZutatZutat
    1BEERBUTTEREGG



    So hätte ich zumindest für die Zutaten eine einzige ID und nicht mehrere. Ein Nachteil wäre aber, dass die Spaltenzahl (oder Länge dieses Zeilenvektros) je nach Anzahl Zutaten variieren kann und ich nicht weiss wie flexibel man Spalteneinträge dynamisch erweitern kann oder ob man nur in vordefinierten Spalten Einträge ablegen kann.


    Hinzu kommt aber auch hier wieder das Problem mit den Mengen. Wie und wo bilde ich diese am schlausten ab. Ich kann diese ja nicht in der gleichen Struktur (als Zeilenvektor) in eine Tabelle legen wie die vorher erwähnten Zutaten. Da eine Zutaten entweder als Stück, über das Gewicht oder als Volumen definiert werden müsste ich entweder die Spaltenanzahl verdreifachen


    _id_ZutStückzahlGewichtVolumenStückzahlGewichtVolumenStückzahlGewichtVolumen
    123856



    oder die Spalten Namen Dynamisch ändern, was aber wiederum nicht funktionieren würde für zukünftige Zutaten, weil diese ja möglicher weise wieder anders definiert sind.


    Es gäbe schon eine Möglichkeit dieselbe Struktur zu nutzen, dann müsste ich aber jeder Zutate noch die Zusatz Information geben ob es sich um eine Stückeinheit,Flüssigkeit oder Fesstoff handelt. Diese Lösung würde dann wieder eine zusätzliche Tabelle benötigen was mir dann schon recht komplex erscheint für eine eigentliche simple Abbildung von Daten. Ich wäre froh wenn mir da jemand mit Erfahrung seine Sicht der Dinge und Ideen näher bringen könnte bevor ich in eine Richtung los laufe und merke, dass ich in einer Sackgasse angekommen bin.

  • Also, zu ersterem: Es ist gewollt das es zu einem rezept mehrere Einträge gibt mit verschiedenen Zutaten, das ist nicht schlimm und so kannst du beliebig viele Zutaten hinzufügen. Die Tabelle wird dann zwar recht groß, aber das schadet nicht solang du keine millionen rezepte hast. Den Cursor interessiert nicht wie du etwas gespeichert hast, der enthält nur die Ergebnismenge. Aber Ja, die SQL Abfrage ist natürlich etwas komplizierter, dafür aber auch dynamischer.


    Die Menge einer Zutat ist ja aber von Rezept und Zutat abhängig und nicht nur von Zutat. Daher solltest du die Menge nicht in Zutat speichern, sondern in der Zwischentabelle. Also da hast du dann _id_ASSO, _id_Zutat, _id_Rezept, Menge.


    Spaltenanzahlen dynamisch ändern geht meines wissens nicht so einfach, ist auch keine sehr hässliche Lösung.


    Wenn du ganz modern sein willst, kannst du dir auch NoSQL datenbanken anschauen. Ich denke aber das es dir erstmal leichter fällt, sql zu lernen als NoSql.

  • Wie meinst du das, "Die Menge einer Zutat ist ja aber von Rezept und Zutat abhängig und nicht nur von Zutat". Wieso genau würdest die Mengen in eine weitere Tabelle auslagern statt sie zusammen mit den Zutaten zu lassen? Ich versteh das schon so, dass je nach Rezept eine andere Menge der Zutat verwendet wird, aber ich hatte jetzt eigentlich die Idee, eine Zutat könnte mehrmals vorkommen in der Datenbank.


    Deine Idee wäre es demnach, wenn ich das richtig verstehe, einen einzigen Pool an möglichen Zutaten zu besitzen und diesen dann über die Ids und Mengen mit den Rezepten in Beziehung zu setzen? So dass nicht mehrmals eine Zutat in der Datenbank angelegt wird, sondern eine einzige jeder Art, welche dann einfach mehrmals über deren Id referenziert wird?


    Falls du das so meinst klingt das recht interessant und eleganter als meine erst genannte Variante. Stelle mir das auch viel übersichtliche vor so.

  • Hab ich oben doch geschrieben, die menge der zutat sollte in der assoziationstabelle stehen. In jedem Rezept wird eine andere Menge einer Zutat benötigt. Natürlich kann eine Zutat in Rezept A und in Rezept B vorkommen. in Rezept A brauchst du aber eben 50g und in Rezept B 100g. Deswegen kannst du die Menge nicht in der Zutaten Tabelle unterbringen.


    Und ja so wie du es beschrieben hast meine ich das :P

  • Benötigt man spezielle Befehle wenn man mit einem Cursor auf die Spalte mit den FOREIGN KEYS zu greifen möchte?


    Wenn ich auf die Spalte mit dem FOREIGN KEY zugreifen möchte mit cursor.getLong(nummerDerKeySpalte) bekomme ich Exception "java.lang.IllegalStateException: Couldn't read row 0, col 5 from CursorWindow.......


    Irgendwie scheint die Spalte gar nicht sichtbar zu sein. Ich kann zur Laufzeit mit keinem gängigen Befehl wie Cursor.getXXX(nummerDerKeySpalte) zu greifen. Ebenfalls wird sie bei Cursor.getColumnCount() nicht mitgezählt.


    Ich hab die Datenbank aus dem Emulator rausgezogen und im "DB Browser for SQLite" angeschaut. Spalten sind alle vorhanden und auch die jeweiligen id Einträge der FOREIGN KEY Spalten stimmen. Also die Datenbank scheint korrekt abgespeichert zu sein nur zugreifen darauf kann ich nicht.


    Ich hab die Spalte auch explizit im OnCreate String als Foreign Key Spalte deklariert mit "FOREIGN KEY(KeySpalte) REFERENCES TabelleDieMitKeyDerReferenziertWird(id)".


    Mach ich was grundsätzliches falsch beim Zugriff auf diese Spalten oder sollte der Zugriff gleich verlaufen wie auf andere Spalten?

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!