1:n Beziehung

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von raist10.

    Hallo Leute,
    ich habe seit gestern mit dem Datenbank-programmieren angefangen und hab' bisher nur geschafft Datensätze in eine Tabelle einzufüllen und wieder auszulesen.
    (Dank ein paat sehr schöner SQL-Syntax Tuts hab ich auch schon ein bisschen SQL gelernt :) )
    Bald bin ich in meinen Büchern und Tuts auf 1:n Beziehungen gestoßen, habe aber nur soviel verstanden, dass Irgendeine Tabelle soetwas wie eine Untertabelle besitzen kann :S


    Jetzt bin ich aber ein wenig hilflos.
    Wie mache ich es, Einträge in die Untertabelle einzutragen?

    So mal nicht ^^
    Ist auch irgendwie unlogisch, schließlich habe ich die Beziehung in einem DataSet gemacht und ich gehe direkt auf die Datenbank :wacko:
    Aber wie soll es sonst gehen?


    Oder hab ich was falsch verstanden? Verwendet man die 1:n - Beziehung nicht so?

    Edit by der_Kurt:
    Bitte keine Doppelposts. Benutze dafür den "Bearbeiten"-Button
    * Beiträge zusammengefügt *

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „der_Kurt“ ()

    Du hast was falsch verstanden ... 2 Tables die über eine 1:n Relation miteinander in Beziehung stehen teilen sich NICHT in eine Art Master und Slave auf. Es sind beides nach wie vor völlig gleichberechtigte Tables.

    Du kannst also in dem jedem genauso wie bisher Datensätze eintragen. Berücksichtige folgende Grundregeln dabei:

    1. Normalerweise hat jedes Table seine eigene ID als Primary Key (Primärschlüssel). Ausnahme von der Regel sind Tables bei denen mehrere Foreign Keys (siehe nachstehend) zusammen als Primary Key dienen.

    2. Wird eine 1:n Beziehung zwischen zwei Tables erstellt, dann wird der Primary Key des Tables das auf der 1-Seite steht in dem Table das auf der n-Seite steht als Foreign Key (Fremdschlüssel) eingetragen. Dadurch kann über den Foreign Key immer eindeutig und unzweifelhaft nachvollzogen werden welche Datensätze aus dem Table auf der n-Seite zu dem Datensatz im Table auf der 1-Seite gehören.

    3. Ein Table kann mehrere Foreign Keys aufnehmen. Wenn nötig kann sogar der Primary Key eines Tables sich aus einer Kombination von Foreign Keys zusammen setzen.

    4. Ist die Beziehung verpflichtend, sprich der Foreign Key ist als Mandatory (NOT NULL) gekennzeichnet im Table auf der n-Seite, dann kannst Du in dem Table auf der n-Seite nur Datensätze anlegen wenn der Foreign Key eine ID beinhaltet die auch im Table auf der 1-Seite vorkommt.

    Hoffe das hilft Dir weiter. ;)

    Gruß

    Rainer
    ich glaub, hier muß exakt gesprochen werden. Besitzen ist schomal ein komisches Wort inne Programmiererei.
    Eine Tabelle ist eine Auflistung von Datensätzen.
    Jeder Datensatz hat Werte. Kannstedir vorstellen wie Properties eines Objekts. Welche Properties die Datensätze einer Tabelle haben ist definiert als ihre Tabellenspalten.
    Eine dieser Tabellenspalten definiert man immer als PrimaryKey, d.h. der Wert für diese Property muss innerhalb der Tabelle einmalig sein.

    Daher isses ganz unlogisch zu sagen eine Tabelle besitzt den Primkey der übergeordneten - weil der Primkey ist eine Tabellenspalte in einer Tabelle, die kann keine andere Tabelle besitzen.

    Die untergeordnete Tabelle hat eine Foreignkey-Spalte. Werte dieser Spalte sind identisch mit einem Primkey-Wert der übergeordneten Tabelle.
    Angenommen ein Datensatz aus TabelleA hat als Primkey-Wert die 93.
    Und ein Datensatz aus TabelleB hat als Foreignkey-Wert ebenfalls die 93.
    Dann verweist dieser TabelleB-Datensatz auf den TabelleA-Datensatz.
    Nun können in TabelleB natürlich beliebig viele Datensätze auf den TabelleA-Datensatz 93 verweisen.
    Mir scheint, im Dataset hast du die Relation falsch eingerichtet, und in der Datenbank überhaupt nicht.

    Denn wenn in der DB eine Fremdschlüsselbeziehung bestehen würde, könnten die Daten, die du abrufst niemals so eingegeben werden - die Beziehung würde das verhindern.

    Aber ich hatte doch auch erklärt, die untergeordnete Tabelle müsse eine FremdschlüsselSpalte bekommen. Wie heißt in deiner DB die Fremdschlüsselspalte?
    Und wie heißt die PrimkeySpalte der Tabelle Artikel?
    Hast du dirmal die beim Tut beiliegende Solution angeguckt, inklusive der Datenbank?

    Memo schrieb:

    Da ist dem aber nicht so: ^^


    Juup, weil Du es falsch gemacht hast. ^^

    Erstens ist die Beziehung auch völlig falsch aufgebaut. Die muss genau andersrum sein. Die n-Seite ist das Table Artikel und die 1-Seite ist das Table Lieferanten.

    Dann musst Du in dem TableArtikel (weil n-Seite) eine neue Column anlegen. Der gibst Du z.B. den Namen IDLieferant und die Column muss den gleichen Daten-Typ haben wie die ID Spalte im Table Lieferanten. Und nun ziehst Du eine 1:n Beziehung von Table Lieferant zum Table Artikel und verbindest darin das Field ID aus Lieferant mit dem Field IDLieferant aus Artikel.

    Dann passt die Geschichte.


    Also besitzt die untergeordnete Tabelle auch noch den Primary-Key von der Übergeordeten?


    Nein, sie bestitzt ihn nicht sondern sie kennt ihn. Muss ja so sein, woher soll sonst der Artikel wissen von welchem Lieferant er stammt? ;)


    Irgendwie gibts es vor der Bezieung genauso viele Einschränkungen wie nach.
    Was verändert die Beziehung eigentlich?


    Meistens gibt es mehr nach der Einrichtung einer Beziehung, zumindest wenn diese referentielle Integrität herstellt.

    Die Beziehung bewirkt folgendes:

    Wenn ein Artikel die ID eines Lieferanten als Foreign Key (also im oben eingrichteten Feld IDLieferant) hält, kann ein Lieferant in der Datenbank nicht mehr gelöscht werden ... oder wenn er gelöscht werden kann, werden ALLE Artikel die seine ID als Foreign Key halten gleich mit gelöscht.

    Das stellst Du in der Beziehung ein mit "ON DELETE UPDATE" (für löschen aller Datensätze die den Foreign Key halten/kennen) oder "ON DELETE NONE" (dann kann ein Lieferant nicht mehr gelöscht werden sobald ein Artikel den Foreign Key auf ihn hält/kennt).

    Dazu kannst Du noch Angaben ob das Feld IDLieferant leer (NOT MANDANTORY) sein kann oder einen Inhalt haben muss (MANDATORY/NOT NULL). Bei letzterem kannst Du dann nur einen Artikel speichern wenn Du im Feld IDLieferant einen Foreign Key eingetragen hast der natürlich auch exakt so im Table Lieferanten vorkommt.

    Das Ganze nennt man dann referentielle Integrität.

    Zusätzlich stellt der Foreign Key natürlich immer die Information da, welcher Artikel gehört zu welchem Lieferant. Und eh klar ... Primary Key und Foreign Key Fields werden automatisch indexiert um Zugriffe zu beschleunigen.

    Du solltest hier noch ganz dringend Dir einiges an Basis-Wissen aneignen, sonst wird das nie was. ;)

    EDIT:

    [klugscheissmodus on]

    ich habe seit gestern mit dem Datenbank-programmieren angefangen


    Eine Datenbank programmiert man nicht, sondern man entwickelt sie. Die Datenbankzugriffe und das GUI programmiert man. ^^
    [/klugscheissmodus off]

    Gruß

    Rainer

    raist10 schrieb:

    Erstens ist die Beziehung auch völlig falsch aufgebaut. Die muss genau andersrum sein. Die n-Seite ist das Table Artikel und die 1-Seite ist das Table Lieferanten.

    Dochdoch, die Richtung der Relation stimmt schon so.
    Im typisierten Dataset zeigt das Schlüssel-Symbol die 1-Seite einer Relation an. Dummerweise sieht das schlüsselchen ungefähr aus wie eine Pfeilspitze, sodass man denkt Artikel->Lieferanten.
    Auch die n-Seite ist eiglich korrekt symolisiert: mit einer liegenden 8. Aber auch kaum zu erkennen.

    Aber deswegen isses natürlich immer noch fehlerhaft, und Memo kommt hoffentlich drauf, wenner meine Fragen beantwortet.

    raist10 schrieb:

    Du solltest hier noch ganz dringend Dir einiges an Basis-Wissen aneignen, sonst wird das nie was. ;)

    Das hab' ich mit Hilfe meines Buches versucht. Leider habe ich da einiges nicht verstanden.

    Äh und ja:
    Ich habe kein Access-Datenbank sondern irgendeine SQLCe (scc)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Memo“ ()

    Dann liegt dir also hoffentlich ein lauffähiges Sample mit einer 1:n-Relation vor.

    Auf dieselbe Weise musstehalt die Tabellen und die Beziehung in der SCC-DB einrichten, und dann kannste genau wie im Tut gezeigt vorgehen.

    Aber meine anneren beiden Fragen haste immer noch nicht beantwortet:
    Wie heißt in deiner DB die PrimkeySpalte der Tabelle Artikel?
    Und wie heißt die Fremdschlüsselspalte, deren Werte auf die Tabelle Lieferanten verweisen sollen?
    Ich hatte eigentlich vorher versucht es im Bild darzusellen indem ich die Beziehungslinie etwas verändert habe ;)

    Aber ich habe im Tut schon eine (funktionierede ;)) 1:n Beziehung zusammengebracht. Ich versuche gerade diese auf Scc umzulegen ^^

    EDIT: Gut habe es geschafft :)

    Dann werde ich jetzt die anderen Beziehungen lernen 8-)
    (Schließlich darft ein Lieferant auch mehr als einen Artikel Liefern ;) )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Memo“ ()

    Memo schrieb:


    EDIT: Gut habe es geschafft :)

    Dann werde ich jetzt die anderen Beziehungen lernen 8-)
    (Schließlich darft ein Lieferant auch mehr als einen Artikel Liefern ;) )


    Und jetzt ist aber die Beziehungsrichtung wirklich falsch. ^^

    Lies Dir nochmal meinen Post von oben durch zum Thema Beziehung und Primary Key/Foreign Key.

    Gruß

    Rainer
    Warum falsch? (Leider sieht man die Spalte ArtikelID im DataGridView nicht)
    Ich habe doch einen Primärschlüssel bei Artikel und einen Fremdschlüssel bei den Lieferanten.
    Und ich hab's ausprobiert - bei "ArtikelID" lassen sich wirklich nur Werte eintragen, die es auch in ID gibt.
    Damit kann ich dann nachvollziehen Welcher Lieferant welchen Artikel liefert ^^
    (Schade das es nicht mit mehreren Artikel geht :pinch: )

    Memo schrieb:


    (Schade das es nicht mit mehreren Artikel geht :pinch: )


    Genau deswegen ist die Beziehung falsch.

    Oder meinst Du etwa das Firmen die große Lager mit Datenbanken verwalten immer nur einen Artikel pro Lieferant haben? ;)

    Natürlich funzt die Beziehung deren Beschränkungen. Sie ist also nicht technisch falsch, sondern sie ist logisch falsch.

    Drehe die Beziehung um, so das die ID des Lieferanten als Foreign Key im Table Artikel steht.

    Was passiert dann? Richtig, nun können mehrere Artikel die ID zu einem Lieferanten als Foreign Key halten.

    Was hast Du damit erreicht? Richtig, zu einem Lieferanten kannst Du mehrere Artikel zuordnen und natürlich auch abfragen. ;)

    Gruß

    Rainer

    Memo schrieb:

    Stimmt ^^
    Aber wie mache ich es das mehrere Lieferanten die gleichen Artikel liefern?


    Das wäre eine klassische m:n Beziehung die nur über ein Zwischentable aufzulösen ist. ;)


    tblArtikel - 1:n - tbl_MN_Artikel2Lieferanten - n:1 - tblLieferanten

    ArtID (PK) ........ ArtID (FK, PK)
    ....................... LieID (FK, PK) ............................ LieID (PK)



    Gruß

    Rainer