Frage

Ich habe eine Frage zu zwei Datenbanken (in Oracle 10G), die ich habe, nennen wir sie A und B. A haben einige Informationen (in verschiedenen Tabellen) und ich möchte, dass B eine teilweise Kopie einiger Tabellen von a erhalten und ständig überprüfen Änderungen in A und 'synchronisieren' sie in B.

Ich möchte Sie nach einer Methode, Technik oder Ideen fragen, da ich weiß, dass ich keine Änderung in a vornehmen kann (nur ausgewählt, keine Auslöser).

Ich danke Ihnen Hilfe und Geduld (für mögliche Änderungen) im Voraus.

Zusätzliche Information:

Vielen Dank für die Antworten, ich weiß nicht, ob es relevant ist, aber ich habe den Minus -Operator gefunden, obwohl ich nicht sicher bin, ob er mit einer "Subtabelle" (Select) funktioniert.

War es hilfreich?

Lösung

Ihre Optionen sind aufgrund Ihrer Anforderungen, "ständig zu überprüfen ... Synchronisieren" und "keine Änderungen in einem" vorzunehmen. Dinge wie materialisierte Ansichtsprotokolle, dbms_alert, Streams und eine Standby -Datenbank sind alle nicht in der Tabelle.

Wenn die Tabellen in A ständig alle ihre Zeilen aktualisieren lassen, wäre eine materialisierte Ansicht (wie Jack Douglas sagte) eine materialisierte Ansicht am einfachsten zu richten. In dem wahrscheinlicheren Fall, dass sich die meisten Datensätze nicht von Moment zu Moment ändern, möchten Sie wahrscheinlich ein Paket (oder Pakete) auf B einrichten, das von A zum Zusammenführen und Löschen nach Bedarf auf B. Seien Sie nur so aktuell wie die Häufigkeit, in der es ausgeführt wird, aber angesichts Ihrer Anforderungen kann es das Beste sein, was Sie tun können.

Insbesondere sollte Ihr Paket Folgendes ausführen:

  • Löschen aus B -Zeilen, die in A nicht existieren, nicht existieren
  • Verschmelzen A in B -Aktualisierung, wenn sie angepasst und einfügen, wenn sie nicht übereinstimmt.

Wenn Sie vermeiden möchten, in einem mehrmaligen Treffer die Tabelle zu treffen, können Sie die gesamte Tabelle in eine globale temporäre Tabelle auf B einfügen und dann Ihre Löschen/Zusammenführungen von dort aus durchführen.

In Bezug auf Minus: Minus Kann Ihnen alle Zeilen von einer Abfrage von a sagen, die nicht in B. Union in der Union mit B abzüglich Abfrage von a Sie alle unterschiedlichen Zeilen erhalten, aber dies würde wahrscheinlich noch länger dauern, bis er das Hinzufügen des Einsatzes verarbeitet würde /Aktualisierungsteil. Wenn A keine Updates oder Deletten erhält, können Sie die Ergebnisse des ersten Minus einfügen, aber ein insert into B...where not exists A... wäre immer noch schneller und einfacher.

Andere Tipps

Es gibt keine Möglichkeit zu wissen, dass sich eine Tabelle in einem geändert hat, außer durch Wahlabfragen. Sie können materialisierte Ansichten in Betracht ziehen, die regelmäßig erfrischt, die über einen DBLINK funktionieren können - aber nur eine vollständige Aktualisierung ist möglich, sodass dies nur dann praktisch ist, wenn die Tische klein sind.

Schwierig, da Sie keinen Zugriff haben, der über eine Auswahl in db_a hinaus keinen Zugriff hat. Hier ist ein Gedanke, aber es erfordert einige ziemlich strenge Annahmen, die erfüllt werden können (oder auch nicht):

Anforderungen:

  • Alle Tabellen, die synchronisiert werden, haben beide:
    • Ein Zeitstempel (desto mehr Auflösung desto besser)
    • Eine eindeutige, sequentielle ID
  • Alle Tabellenreihen, sobald sie synchronisiert sind, ändern sich nicht.
    • Wenn eine Änderung stattfindet und einen Zeitstempel auf dem Datensatz aktualisiert, können Sie dies möglicherweise so ausarbeiten.

Jetzt auf DB_B:

CREATE TABLE table1...
CREATE TABLE table2...,
etc.

PROCEDURE SYNC_TABLE1 IS
    MAX_ACTIVITY_DATE DATE;
    MAX_SEQUENCE_NO NUMBER;

    BEGIN
        SELECT MAX(SEQUENCE_NO), MAX(ACTIVITY_DATE) 
          INTO MAX_SEQUENCE_NO, MAX_ACTIVITY_DATE
          FROM table1;
    EXCEPTION WHEN NO_DATA_FOUND THEN
        MAX_SEQUENCE_NO := 0;
        MAX_ACTIVITY_DATE = TO_DATE('01/01/1980', 'MM/DD/YYYY');
    END;

    -- Bring over recent entries from db_A.table1 to db_B.table1

    INSERT INTO table1
    SELECT *
      FROM table1@db_A
     WHERE
           -- if using timestamps as your criteria:
           activity_date > MAX_ACTIVITY_DATE
           -- if using sequence nos as your criteria:
           sequence_no > MAX_SEQUENCE_NO
    ;

    -- consider adding limiters to decrease the bandwidth necessary
    -- for large transactions. For example activity_date < MAX_ACTIVITY_DATE + 30
    -- would load a month's worth of transactions at a time. sequence_no <
    -- MAX_SEQUENCE_NO + 500 would load 500 transactions at a time.

    COMMIT;
EXCEPTION WHEN OTHERS THEN
    ROLLBACK;
    -- Consider logging the error!
    RAISE;
END;
(lather, rinse, repeat.)

Dies funktioniert nur dann nur, wenn Sie entweder eine sequentielle eindeutige ID oder ein Aktivitätsdatum haben, das immer auf DB_A aktualisiert wird (und dieses Datum sollte eine ausreichende Auflösung haben, um eine Transaktion nach der vorherigen einfügten Transaktion zu erkennen, sodass die Zeitstempel am besten sind.)

Die Art und Weise, wie ich Daten zwischen Oracle-Instanzen (und Nicht-Oracle-Instanzen, z. B. Oracle to MySQL) synchrone, besteht darin, sicherzustellen, dass ich eine Sync_date-Spalte in allen meinen synchronisierbaren Tabellen habe. Wenn eine Anforderung an Synchronisierungsdaten gestellt wird, wird diese Sync_date -Spalte mit dem Datum der Synchronisierung ausgefüllt. Daher ist der tatsächliche Synchronisierungsvorgang einfach:

FOR r in ( SELECT * FROM table1
            WHERE sync_date IS NULL ) LOOP
    send_sync_data_somewhere;
    UPDATE table1
       SET sync_date = current_timestamp
     WHERE rowid=r.rowid;
END LOOP;

Normalerweise tritt ein Begrenzer in Kraft, aber Sie haben die Idee. Wenn sich die Daten in einem Datensatz ändert, ist die Spalte Sync_date nulled. An diesem Punkt wird der Synchronisierungsvorgang wieder aufgenommen.

HINWEIS: Unabhängig von der Situation benötigen Sie eine Art De-Do-Duplikations-Handhabung, wenn Sie Datenänderungen unterstützen können, sobald eine Zeile synchronisiert wurde. Sie können eine Zusammenführung oder einen Einsatz mit einem Wo nicht in der Auswahlklausel in Verbindung mit einem Update ... wo existiert.

Hoffentlich hilft das.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top