Aco: Daten einer Tabelle in eine andere übertragen

Hallo zusammen,

ich soll einen routing algorithmus in php programmieren und die routingtabellen in einer datenbank abspeichern.

zur zeit habe ich fünf router (in fünf tabellen), es können jedoch weitere hinzugefügt, bzw. weggenommen werden.

mein aktueller datensatz:

router_a

target|costs|gateway
---------------------
B     |2    |B
D     |1    |D
E     |1    |E

router_b

target|costs|gateway
---------------------
A     |2    |A
C     |1    |C
D     |1    |D

router_c

target|costs|gateway
---------------------
B     |1    |B

router_d

target|costs|gateway
---------------------
A     |1    |A
B     |1    |B
E     |1    |E

router_e

target|costs|gateway
---------------------
A     |1    |A
D     |1    |D

so sehen die tabellen nach dem ersten schritt aus. alle haben drei spalten mit denselben spaltennamen. die informationen  werden über ein html-eingabeformular übermittelt.

nun sollen die router allerdings ihre tabellen, wo im moment nur benachbarte router drin stehen, miteinander austauschen. konkret bedeutet das z.b. für router_a, nachdem er die tabelle von router_b erhalten hat:

router_a

target|costs|gateway
---------------------
B     |2    |B       \ D     |1    |D       -> alte einträge
E     |1    |E       /
A     |4    |B       -> dieser eintrag müsste wegfallen, da redundant
C     |3    |B
D     |3    |B       -> dieser müsste ebenfalls weg
       |     +--------> als gateway wird überall router_b eingetragen
       +--------------> costs von router_a mit router_b addieren

die neuen informationen sollen nicht einfach mit der alten tabelle verknüpft werden, sondern in die bestehende tabelle reingeschrieben werden. alle doppelten einträge sollen gelöscht werden, bzw. einträge mit niedrigsten costs sollen behalten werden.
wenn ich z.b. router_a nach router_b, costs 2 eingebe, dann soll der umgekehrte eintrag auch sofort in die tabelle von router_b geschrieben werden.

das ist mein erstes "größeres" projekt mit mysql-datenbanken. mein wissen ist noch sehr beschränkt, ich hoffe deshalb, dass ihr mir weiterhelfen könnt!

vielen dank im voraus!

  1. Hi,

    dazu habe ich zwei Anmerkungen:

    1. Das ist ein extrem unglückliches Tabellendesign, denn deine Probleme siehst du ja mittlerweile selbst. Günstiger wäre eine Tabelle mit zusätzlichen Informationen wie einer Nachbarschaftsgruppe oder sowas. Verschieben wäre dann _ein_ einfaches Update.
    2. Deine Verschiebeoperationen sind eine Folge von INSERT und DELETE-Anweisungen, die du am Besten in einer großen Transaktion klammerst um einem Datenverlust vorzubeugen. Wenn du doppelte Einträge verhindern willst, wirst du noch SELECTs dazwischenmischen müssen.

    MfG
    Rouven

    --
    -------------------
    ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
    1. Hallo Rouven,

      Hi,

      dazu habe ich zwei Anmerkungen:

      1. Das ist ein extrem unglückliches Tabellendesign, denn deine Probleme siehst du ja mittlerweile selbst. Günstiger wäre eine Tabelle mit zusätzlichen Informationen wie einer Nachbarschaftsgruppe oder sowas. Verschieben wäre dann _ein_ einfaches Update.
      2. Deine Verschiebeoperationen sind eine Folge von INSERT und DELETE-Anweisungen, die du am Besten in einer großen Transaktion klammerst um einem Datenverlust vorzubeugen. Wenn du doppelte Einträge verhindern willst, wirst du noch SELECTs dazwischenmischen müssen.

      MfG
      Rouven

      danke erstmal für deine antwort!
      könntest du mir ein beispiel einer solchen anweisung geben?
      würde das in etwa so aussehen?

      INSERT INTO router_a (target, costs) VALUES (target router_b, costs router_b)

      es wurde mir leider in der schule so vorgegeben, dass für jeden router eine eigene tabelle angelegt werden soll!

      MfG

      1. Hi,

        könntest du mir ein beispiel einer solchen anweisung geben?
        würde das in etwa so aussehen?

        INSERT INTO router_a (target, costs) VALUES (target router_b, costs router_b)

        Das Insert von Daten aus einer anderen Tabelle ist eine Kombination von INSERT und SELECT:
        INSERT INTO router_a (target, costs)
        SELECT target, costs
        FROM router_b
        <Kriterienausdruck>

        MfG
        Rouven

        --
        -------------------
        ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
        1. hallo,

          Das Insert von Daten aus einer anderen Tabelle ist eine Kombination von INSERT und SELECT:
          INSERT INTO router_a (target, costs)
          SELECT target, costs
          FROM router_b
          <Kriterienausdruck>

          MfG
          Rouven

          ich werde es heute ausprobieren. vielen dank für die hilfe!

          1. also das funktioniert soweit. jetzt habe ich nur noch ein problem: ein router soll die tabellen von allen anderen routern bekommen, die als target in seiner routingtabelle drinstehen. bei router_a wären das router_b, router_d und router_e.
            außerdem müssen danach die costs von router_a nach router_b (also 2) mit den costs aller neuen router, die router_a von router_b bekommen hat (z.b. C, 2+1=3), addiert werden.

            im moment sieht der code bei mir an dieser stelle so aus:

            $all_routers = mysql_query("SHOW TABLES FROM database");
            while ($row = mysql_fetch_row($all_routers)) {
               $abfrage = "INSERT INTO ".$row[0]." (target, costs)
                           SELECT target, costs
                           FROM ".$row[1];
               $ergebnis= mysql_query($abfrage);
            }

            irgendwie versteht er aber nicht, dass er bei $row[1] ab dem zweiten index hochzählen soll. kann mir jemand helfen?

            1. Hi,

              irgendwie versteht er aber nicht, dass er bei $row[1] ab dem zweiten index hochzählen soll. kann mir jemand helfen?

              kannst du mir bitte erklären, was du damit meinst? in $row[1] steht der Wert der zweiten Spalte des aktuellen Datensatzes. Wenn der sich ändern soll, musst du ihm sagen wie.

              MfG
              Rouven

              --
              -------------------
              ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
              1. Hallo,

                Hi,

                irgendwie versteht er aber nicht, dass er bei $row[1] ab dem zweiten index hochzählen soll. kann mir jemand helfen?
                kannst du mir bitte erklären, was du damit meinst? in $row[1] steht der Wert der zweiten Spalte des aktuellen Datensatzes. Wenn der sich ändern soll, musst du ihm sagen wie.

                MfG
                Rouven

                mein aktueller stand für router_a ist folgender:

                router_a

                target|costs|gateway
                ---------------------
                B     |2    |B
                D     |1    |D
                E     |1    |E
                C     |1    |B
                D     |1    |B

                bis auf die spalte costs stimmt alles. ich müsste doch jetzt mit einem UPDATE die spalte costs, in der target=B, mit den spalten, in denen target!=B && gateway=B, addieren.
                das habe ich bisher aber leider noch nicht hingekriegt.

                Gruß

                1. Hi,

                  na dann, dann mach das doch:
                  Zunächst mal bleibt da ja immer der manuelle Ausweg, der springt mir in den Kopf eh ich mir länger Gedanken darüber mache, das in ein Statement zu verpacken:
                  Mit PHP 2 Abfragen machen

                  1. SELECT SUM(costs) FROM router_a WHERE target <> 'B' AND gateway = 'B'
                    -> Gesamtkosten aller targets, die über B nach nicht B führen
                    -> Ergebnis als $zusatzkosten
                  2. UPDATE router_a SET costs = costs + $zusatzkosten WHERE target = 'B'

                  So, damit wäre der Schritt erledigt, enn ich deine Beschreibung richtig deute...

                  Nun kann man noch versuchen, das in ein Statement zu bringen.
                  Da fallen mir verschiedene Varianten ein, aber alle brauchen irgendwie einen JOIN oder ein SUBSELECT und hängen damit vom Datenbanksystem ab.
                  Hier ist z.B. ein Eintrag aus dem MySQL-Fehlerarchiv, in dem so ein Update mit JOIN beschrieben wird. Aber das wird glaube ich schon recht heikel, mit einer STORED PRODECURE ginge es schön und schnell...

                  MfG
                  Rouven

                  --
                  -------------------
                  ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
              2. Oh sorry,

                mein vorheriger beitrag hatte inhaltlich nicht viel mit der von dir zitierten stelle zu tun ;)

                Hi,

                irgendwie versteht er aber nicht, dass er bei $row[1] ab dem zweiten index hochzählen soll. kann mir jemand helfen?
                kannst du mir bitte erklären, was du damit meinst? in $row[1] steht der Wert der zweiten Spalte des aktuellen Datensatzes. Wenn der sich ändern soll, musst du ihm sagen wie.

                MfG
                Rouven

                mit anderen worten, ich will eine schleife basteln, mit der router_a seine tabelle mit router_b und umgekehrt austauscht. genauso router_a mit router_d, router_d mit router_e usw.

                danke für deine hilfe!