Erweiterbare/Verzweigte Baumstruktur in datenbank abspeicher

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

Moin,
ich will mein PHP/MySQL Adressbuch gern in Python umschreiben.
Allerdings will ich es auch im ein paar Kleine Details erweitern.
Die wichtigste Erweiterung soll darin bestehen dass ich die Personen in "Gruppen" einteilen können möchte.
-Freunde
__
-Schulfreunde
__-Unifreunde
-Arbeitskollegen
__-Abteilung 1
____-Bereich Nord
____-Bereich Süd
__-Abteilung 2

Also eigentlich eine normale Baumstruktur.
Nun möchte ich aber, dass eine Person auch gleichzeitig Schulfreund sein kann und Arbeitskollege der Abteilung 1 Bereich Süd.
Wie würdet ihr so etwas abspeichern?
Also ich mein eine "row" muss natürlich für die zugehörigkeit im Adressbuch vorhanden sein. Aber wie würdet ihr die Baumstruktur speichern? In einer eigenen tabelle?
Vielen Dank schon mal für eure Hilfe!
Martin
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Ich würde es so machen:

Tabelle "person" mit allen Infos zur Person

Tabelle "category" mit Aufbau:
cat_id, name, parent

Tabelle "personInCategory" mit Aufbau:
p_id, cat_id

Somit kannst du beliebig viele Personen mit beliebig vielen Kategorien ablegen.

Bei der Kategorie ist einfach parent=0 wenn es keine weiteren Kategorien oberhalb mehr gibt.

Gruss
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

http://dev.mysql.com/tech-resources/art ... -data.html

Joa...besser als die Website kann ich es auch nicht erklären :D

Allerdings würde ich dann später nen ORM draufknallen...bei den ganzen Join wird einem ja schwindelig ;)
[ jap. bin ein SQL-Weichei. ]
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

also, wenn ich das richtig verstehe, dann würdet ihr einen Tabelle erstellen, die nur den Aufbau des Baumdiagrammes beinhaltet.
Klar, das von den Personen zu trennen ist vielleicht ganz sinnvoll. Aber eigentlich würde ich dann die "personInCategory" eher einfach in eine Zeile der "person" schreiben.

Nur den Aufbau der "category" verstehe ich noch nicht ganz.
cat_id Klar
name Ich gehe mal davon aus, dass das der Name der Kategorie ist, also beispielsweise Bereich Nord.
parent Nur hier weiß ich jetzt nicht so recht, wie ich das aufbauen soll.
Schreibe ich da einfach die nächst höhergelegene Kategorie hin? Oder gleich den ganzen Pfad?

Vielen Dank schon mal für eure Hilfe!
Martin
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

martinli hat geschrieben:Klar, das von den Personen zu trennen ist vielleicht ganz sinnvoll. Aber eigentlich würde ich dann die "personInCategory" eher einfach in eine Zeile der "person" schreiben.
Somit könntest du nur noch 1 Kategorie pro Person zuweisen, mit einer extra Tabelle kannst du soviel du willst.
martinli hat geschrieben:Nur den Aufbau der "category" verstehe ich noch nicht ganz.
cat_id Klar
name Ich gehe mal davon aus, dass das der Name der Kategorie ist, also beispielsweise Bereich Nord.
parent Nur hier weiß ich jetzt nicht so recht, wie ich das aufbauen soll.
Schreibe ich da einfach die nächst höhergelegene Kategorie hin? Oder gleich den ganzen Pfad?
Beim parent schreibst du nur die cat_id der nächst höheren Kategorie rein, ausser bei den obersten, da kannste 0 reinschreiben.

Gruss
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

Also ich hab das bisher so gemacht, dass ich die Zugehörigkeit zu mehreren Gruppen in einer Tabelle sozusagen mit einer csv gelöst habe:
8a5a0eae251267eb349bf9db3e09712d|
66723baaa17f1304f3ccd72aa5ea4d28|
b4d65d9d077a38b7647b3f1cf31fc2bc|
652d93163631fe003bc24e8f9affd3d1|
5b28a33f6a81e6a99563271ff8b04797|
f587e02939ff7f0474ad57eeb0e39e8c|

Dann sollte es auch klappen mehrere gruppen in eine Spalte zu schreiben.
Aber vielleicht leichter zu bearbeiten ist es natürlich wenn man pro Zeile nur eine Zugehörigkeit definiert.

Vielen dank noch mal!
Martin
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Was sollen uns diese cryptischen Angaben sagen?
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

naja, ich habe in meinem altern adressbuch auch Gruppen, aber nur in zwei ebenen, Also Gruppen und Untergruppen.
Und um nicht nach den Gruppennamen suchen zu müssen, habe ich alles als md5 hast gespeichert.
Wie gesagt, ich habe alle zugehörigkeiten in einer einzigen spalte. Bisher habe ich dafür keine eigene Tabelle angelegt.
Es ist halt die Frage, was besser ist?
Gruß
Martin
BlackJack

Ehrlich gesagt habe ich's immer noch nicht verstanden. Du hast (Gruppen)Namen durch Hashes ersetzt? Und statt nach den Namen, kann bzw. muss man jetzt nach den Hashes suchen?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Und zusätzlich: Du hast alle in einer Spalte stehen und trennst sie durch ein Trennzeichen? (Wenn ja: GANZ schlecht Idee - Verletzung der 1NF!)
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Mein Ansatz: SQLAlchemy, Adjacency List Relationships für Gruppen und 'ne n:m-Verknüpfung mit den Personen (als separate Entität).
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Ja schreib nie mehrere Werte in eine Zelle einer Datenbank, macht abfragen mühsam, verletzt die 1. Normalform (wie schon von Hyperion genannt).

Nimm lieber eine 2. Tabelle und erstell pro Kategoriezugehörigkeit einen Eintrag.

Gruss
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

Hm, also ich suche nach dem hash, weil ich das für eindeutiger halte.
Zudem, kann es bei meinem neuen Vorhaben, eine richtige Baumstruktur zu erstellen auch mal dazu kommen, dass es einen Kategorienamen doppelt gibt. Spätestens da muss eine Kategorie genauer definierbar sein als durch den Namen.
Und zum Thema "Ein Datensatz/Feld":
also eigentlich hab ich das bei fast allen Daten auch so gehandelt.
In der neuen Version möchte ich aber das Adressbuch auch erweitern können. Entweder ich lege zu jeder Erweiterung eine neue Tabelle an, das finde ich eigentlich etwas doof, weil ich dann später eine Vielzahl von Tabellen habe.
Hm, also ich will jetzt nicht sagen, dass ich mir das ganze nicht noch mal überlegen werde, Aber irgendwie werft ihr meine bisherigen Gedanken ein wenig durcheinander!
Vielen dank für eure Hilfe!
Martin
BlackJack

Ein Hashwert ist eindeutiger als *was*? Wenn zwei Kategorien den gleichen Namen haben, dann kommt da auch der gleiche Hashwert heraus. Das ist ja gerade das schöne und praktische an Hashwerten: Gleiche Eingaben ergeben den gleichen Hashwert.

Und ja, bei relationalen Datenbanken hat man am Ende mehrere Tabellen. Das ist das Prinzip einer relationalen Datenbank: verschiedene Tabellen, zwischen denen es Relationen gibt. Daher der Name. ;-)

Wenn es im Baum Knoten mit den gleichen Namen geben kann, dann kann man ganz offensichtlich den Namen nicht als eindeutige ID verwenden. In den meisten Fällen ist es sowieso besser eine künstliche ID zu verwenden.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

martinli hat geschrieben:Hm, also ich suche nach dem hash, weil ich das für eindeutiger halte.
eindeutiger als was?
Zudem, kann es bei meinem neuen Vorhaben, eine richtige Baumstruktur zu erstellen auch mal dazu kommen, dass es einen Kategorienamen doppelt gibt. Spätestens da muss eine Kategorie genauer definierbar sein als durch den Namen.
Wie wäre es durch eine id? ;-) Wobei ich noch immer nicht genau verstanden haben, was eine Kategorie ist!
Und zum Thema "Ein Datensatz/Feld":
also eigentlich hab ich das bei fast allen Daten auch so gehandelt.
In der neuen Version möchte ich aber das Adressbuch auch erweitern können. Entweder ich lege zu jeder Erweiterung eine neue Tabelle an, das finde ich eigentlich etwas doof, weil ich dann später eine Vielzahl von Tabellen habe.
Wieso das denn? Generell kann man die Attribute eines Adresseintrages ja auch in einer Zeile einer Tabelle speichern. Du müßtest also nur bei einem neuen Feld (ICQ-NUmmer o.ä.) einfach eine Spalte dranhängen, nicht aber eine neue Tabelle.
CSV in einer Zelle ist tödlich! Lass es Dir noch mal gesagt sein!
Hm, also ich will jetzt nicht sagen, dass ich mir das ganze nicht noch mal überlegen werde, Aber irgendwie werft ihr meine bisherigen Gedanken ein wenig durcheinander!
Vielen dank für eure Hilfe!
Martin
Das mag daran liegen, dass Du konzeptionelle Fehler machst! Ich kapiere nicht, wieso Du es nicht folgendermaßen löst:

Code: Alles auswählen

create table kontakt (
  // Personendaten
)

create table kategorien (
  id int primary key,
  name varchar,
  parent int,
  foreign key id references (katgegorien.id)
)

// und nun die n:m-Relation

create table kontakt_in_kategorie (
  kontaktid int,
  kategorieid int,
  primary key(kontaktid, kategorieid)
)
Das ist jetzt kein kirrektes SQL, aber sollte die Struktur klar machen. In Kontakt steht ein spezieller User. In Kategorien kannste verschiedene "Gruppen" hierarchisch zusammenpacken. Schließlich kannst Du einer Kategorie einen User zuordnen. Dieser kann in beliebig vielen Kategorien sein und jede Kategorie kann beliebig viele User haben. Das ist es doch, was Du willst?

Als Bonus kannste sogar einer Person nur in einer Gruppe spezielle Attribute zuweisen ;-)
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

ehrlichgesagt ist der Hash wert in meinem fall eine art künstliche ID, da der Name mit der microtime() gesaltet wird.

Also, ich muss sagen, mein Schädel brummt gerade, Ja, ich muss zugeben, je mehr ich darüber nachdenke, desto mehr verstehe ich was ihr meint.
Ihr müsst ja verstehen, dass ich vom bildungsstand her nicht im Ansatz programmierer bin, auch wenn ich während meines Studiums mal ein semester ein fach hatte, das sich Informatik nennt. Aber ok, das kann man vergessen.
Also, vielen Dank noch mal für eure Hilfe.
Martin
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Schreib Dir einfach mal ein paar Datensätze der Tabellen meiner Struktur auf. Beschränke Dich auf das nötigste und versuche dann mal verschiedene Sachen zu simulieren (ein User in mehreren Kategorien z.B.).

Wenn Du das kapiert hast, versuche das in ner DB umzusetzen und dort mit Queries zu arbeiten.

So solltest Du schnell sehen, was Dir ggf. noch fehlt, bzw. was geht.

Den Baum kann man dann im Programm später leicht rekursiv aufbauen (Suche alle Elemente, deren Parent id=5 ist und hänge sie an den aktuellen wurzelknoten).
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

Tja, bei der Datenbank stellt sich eigentlich die nächste Frage.
Also bisher nutze ich standart MySQL.
Wenn ich das ganze später erweitern möchte, beispielsweise damit mehrere Nutzer das gleiche Adressbuch verwenden können,
Und auch um andere dinge wie Erinnerungen oder ähnliches, dann wäre es vielleicht sinnvoll eine andrer Datenbank zu nutzen?
Ich will hier keinen Streit vom Zaun brechen, über die qualität von Datenbanken, vorteile von der einen oder anderen, aber naja vielleicht könnt ihr mir ja einfach sagen, dass ich ruhigen gewissens bei MySQL bleiben kann!
Vielen Dank!
Martin
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wie kommst Du auf die Idee das DBMS wechseln zu wollen, wo Du ja noch nicht einmal die grundlegende einfache Struktur verstanden hast? Fang damit doch erst einmal an - solltest Du irgend wann an die Grenzen von MySQL stoßen, hast Du so viel Ahnung, das selber zu entscheiden :-D
martinli
User
Beiträge: 10
Registriert: Freitag 25. Januar 2008, 17:54
Kontaktdaten:

Also,
ich würde sagen über den Aufbau der Datenbank hab ich mir jetzt "Reichlich" Gedanken gemacht.
Jetzt würde ich ganz gerne anfangen ein wenig zu Programmieren!
Nun stellt sich wirklich die Frage, welche Datenbank ich nutze. Eigentlich habe ich folgende Ansprüche:
- Wenn möglich soll das Programm später Plattformübergreifend einfach zu installieren sein. Daher wäre es gut, wenn die Datenbank schon im Programm integriert wäre
- Wenn möglich sollte der Datenbankserver nur laufen, wenn auch das Programm läuft, es soll also nicht so sein, wie auf meinem Rechner, wo ich immer 2 Datenbanken gleichzeitig im Hintergrund am laufen habe.
- Gleichzeitig möchte ich aber auch die Möglichkeit haben, online ein Backup zu ziehen bzw. einen Abgleich mit einem online liegenden Adressbuch vorzunehmen
Ich würde mich freuen, wenn ihr hier ein paar Tipps habe!
Vielen Dank schon mal!
Martin
Antworten