Ankündigung

Einklappen
Keine Ankündigung bisher.

Zwei Tabellen die 1:n Beziehungen zu einer 3. Tabelle haben

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Zwei Tabellen die 1:n Beziehungen zu einer 3. Tabelle haben

    Angenommen ich habe eine TabelleA und TabelleB, wobei beide eine 1:n Beziehung zu TabelleC haben. Wie sollte man diese Beziehungen speichern? Mir fallen da spontan 2 Möglichkeiten ein:

    Ich lege eine Tabelle TabelleC-Set an welche lediglich einen Primärschlüssel pro Datensatz definiert und eine 1:n Beziehung mit TabelleC aufweist. TabelleA und TabelleB nehmen anschließend einen 1:1 Beziehung mit TabelleC-Set ein.

    Zweite Möglichkeit wäre das Ganze über die Tabellen TabelleA_2_TabelleC und TabelleB_2_TabelleC zu lösen.

    Welche Variante wählt man in solch einem Fall?


    Mfg


  • #2
    Mach mal bitte nen Praktisches beispiel. a_to_c und b_to_c wäre wohl das Standardvorgehen hier.
    Zitat von nikosch
    Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.

    Kommentar


    • #3
      Gewöhnlicherweise bildet man 1:n Beziehung mit einem Fremdschlüssel auf der n Seite ab. Das heißt du legst in TabelleC je eine Spalte für den PK von TabelleA an und ein für den PK von TabelleB.

      Kommentar


      • #4
        Zitat von erc Beitrag anzeigen
        Gewöhnlicherweise bildet man 1:n Beziehung mit einem Fremdschlüssel auf der n Seite ab. Das heißt du legst in TabelleC je eine Spalte für den PK von TabelleA an und ein für den PK von TabelleB.
        TabelleA und TabelleB dürfen aber nicht die selben Beziehungen zu TabelleC aufweisen. Bei jedem Datensatz in Tabelle C muss also zumindest ein Fremdschlüssel einen Null-Wert haben - wäre das nicht etwas unsauber?

        Mach mal bitte nen Praktisches beispiel. a_to_c und b_to_c wäre wohl das Standardvorgehen hier.
        Ich versuche ein Rechnungssystem umzusetzen, wobei TabelleC einer Tabelle services entspricht. Die anderen beiden Tabellen heißen invoices und recurring_invoices.
        Die Datensätze von recurring_invoices entsprechen nicht richtigen Rechnungen, sondern lassen sich eher als Vorlagen für Rechnungen beschreiben, die ein Zeitintervall definieren, anhand dessen ein Cronjob eine richtige Rechung (abgelegt in invoices) erstellt.
        Wird nun ein service-Datensatz, der einem recurring_invoice-Datensatz zugeorndet ist modifiziert, soll sich das natürlich nicht auf die Rechnungen auswirken, die bereits anhand des recurring_invoice-Datensatzes generiert worden sind. Daher erstellt der Cronjob eine Kopie von sämtlichen service-Datensätzen, die mit dem aktuellen recurring_invoice-Datensatz in Beziehung stehen und verknüpft sie mit einem neuen invoice-Datensatz.

        Kommentar


        • #5
          Das konnte man so nicht raus lesen. Es sind beide Varianten OK bei der Problemstellung. Die Frage ist ob das grundlegende Prinzip sinnvoll ist, lässt sich aber ohne das Ganze zu kennen nicht beurteilen. Aus dem Bauch raus würde ich das aber nicht so umsetzen sondern die invoices separat archivieren.

          Kommentar


          • #6
            Hi,
            Zitat von erc Beitrag anzeigen
            Aus dem Bauch raus würde ich das aber nicht so umsetzen sondern die invoices separat archivieren.
            könntest Du das bitte näher erläutern? Du meinst offene und bezahlte Rechnungen sollten voneinander getrennt werden?

            MfG

            Kommentar


            • #7
              Zitat von Okinez Beitrag anzeigen
              Hi,

              könntest Du das bitte näher erläutern? Du meinst offene und bezahlte Rechnungen sollten voneinander getrennt werden?

              MfG
              In #4 sagst Du: "TabelleA und TabelleB dürfen aber nicht die selben Beziehungen zu TabelleC aufweisen. Bei jedem Datensatz in Tabelle C muss also zumindest ein Fremdschlüssel einen Null-Wert haben" - warum realisierst Du das nicht einfach? Geht ganz easy via CHECK-Constraint:

              Code:
              test=# create table t_a(id int primary key);
              CREATE TABLE
              Time: 360,326 ms
              test=*# create table t_b(id int primary key);
              CREATE TABLE
              Time: 6,923 ms
              test=*# create table t_c(t_a int references t_a, t_b int references t_b, check ((case when t_a is null then 1 else 0 end)+(case when t_b is null then 1 else 0 end) > 0));
              CREATE TABLE
              Time: 39,362 ms
              test=*# insert into t_a values (1);
              INSERT 0 1
              Time: 0,490 ms
              test=*# insert into t_a values (2);
              INSERT 0 1
              Time: 0,148 ms
              test=*# insert into t_b values (2);
              INSERT 0 1
              Time: 0,385 ms
              test=*# insert into t_c values (1,NULL);
              INSERT 0 1
              Time: 2,715 ms
              test=*# insert into t_c values (NULL,NULL);
              INSERT 0 1
              Time: 0,186 ms
              test=*# insert into t_c values (NULL,2);
              INSERT 0 1
              Time: 0,436 ms
              test=*# insert into t_c values (1,2);
              ERROR:  new row for relation "t_c" violates check constraint "t_c_check"
              DETAIL:  Failing row contains (1, 2).
              Time: 0,234 ms
              test=*#
              PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

              Kommentar

              Lädt...
              X