AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Reihenfolge beim einspielen von Tabellen ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Reihenfolge beim einspielen von Tabellen ermitteln

Ein Thema von Jumpy · begonnen am 25. Apr 2012 · letzter Beitrag vom 26. Apr 2012
Antwort Antwort
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.737 Beiträge
 
Delphi 6 Enterprise
 
#1

Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 25. Apr 2012, 14:59
Datenbank: Oracle • Version: 10g • Zugriff über: ADO+ODBC
Hallo,

ich habe eine fertige (leere) Datenbankstruktur vorliegen und muss nun in die Tabellen die Daten importieren. Dabei muss ja eine Reihenfolge beachtet werden, um keine Foreign-Key-Verletzungen zu bekommen, d.h. eine Parenttabelle muss zuerst eingespielt werden, bevor eine Childtabelle eingepielt wird, in der es FK-Constraints gibt, die auf die Parenttabelle referenzieren.

Dazu habe ich (hieran orientiert) einen View erstellt, der zwei Spalten hat: Child (alle Tabellen mit FK) und Parent (die durch den Key refer. Tabelle).

Wie kann ich aus dieser Info, die Reihenfolge ermitteln, in der die Tabellen gefüllt werden müssen? Meine Idee:
1) Alle Tabellen in Parent, die es nicht in Child gibt.
2) -->Hier ist das Problem: Alle Tabellen mit FK in der richtigen Reihenfolge
3) Alle Tabellen, die weder in Child noch in Parent auftauchen, wo also die Reihenfolge egal ist.

1+3 Kann ich per SQL ermitteln.
Wie sieht es mit 2 aus? Das muss man irgendwie Sequentiel durchgehen???

(Nur so für die Größenordnung: insgesamt ca. 3000 Tabellen, davon in meiner obigen abfrage 1100 FK-Constraints die zu beachten sind)
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 25. Apr 2012, 15:13
Während des Imports könntest du auch ganz einfach diese Prüfungen deaktivieren.
$2B or not $2B
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.737 Beiträge
 
Delphi 6 Enterprise
 
#3

AW: Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 25. Apr 2012, 15:56
Schon richtig (war auch meine faule Idee), aber es gibt wohl keine Garantie, dass die Daten sauber sind, weswegen mein Ausbilder möchte, dass es beim Import knallen soll und nicht erst, wenn die Constraints wieder aktiviert werden (falls das dann überhaupt knallt???).
Ralph
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#4

AW: Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 25. Apr 2012, 17:45
Es wird knallen.

Du sortierst deine Tabellen 'topologisch', sodaß jede Tabelle 'A', die einen FK auf eine Tabelle 'B' hat, in der Ordnung höher angesiedelt ist.

Dann hast Du die Reihenfolge, in der die Tabellen zu importieren sind, sodaß es beim Import knallt.

Sage deinem Ausbilder, das seine Vorgabe für das Lernen von Algorithmen sehr sinnvoll ist, aber in der Praxis ziemlich dämlich, denn dadurch wurd der Import sehr viel langsamer. Und Performance ist das, was zählt.

Zudem ist die Vorgabe sehr praxisfremd (ich gehe davon aus, das er die Daten recordweise einlesen lassen will), denn i.a. verwendet man 'bulk insert', um Tabellen zum importieren. Dabei werden diese ohne Rücksicht auf Verluste in die DB geblasen und hinterher per FK auf Konsistenz geprüft, also:

1. Constraints ausschalten
2. BULK INSERT
3. Constraints einschalten

Schneller, und damit praktikabler, geht es nicht. Die zu importierenden Tabellen können i.a. vorher auf referentielle Integrität geprüft werden.
Dies ist natürlich bei TB-großen Tabellen kaum möglich.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#5

AW: Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 25. Apr 2012, 23:21
Ich stimme himizu und furtbichler zu, würde aber vielleicht nicht so drastische Worte wählen.
3000 Tabellen sind nicht wenig, es müssen ja aber nicht viele Daten drin sein...

Vermutlich musst Du (selbst) auf dem Vorgang mehrere Schleifen drehen, bis es einmal nach Vorgabe klappt. Erfahrungsgemäß ist die Datenqualität von "beliebigen" DB immer schlechter als erwartet, Ref Constraints können schon Luxus sein. Nicht wegen der Importproblematik, sondern weil es überhaupt definierte Beziehungen gibt.

In meinen Augen ist so ein "freier" Import vergleichbar mit ETL Prozessen. Wenn ich es mir (oder der Maschine) erlauben kann, mache ich das relativ rotzig- also nicht ETL- Lade alles und mach danach auf DB Ebene das ET. Initial, versteht sich, soll ja klassischerweise dann mal später automatisiert laufen.

Ähnlich ist es bei einem Import einer DB. Trotz der definierten Constraints kannst Du leider nicht davon ausgehen, dass alles wie Butter läuft, wenn Du die richtige Reihenfolge berücksichtigst. Constraints abzuschalten geht, wurde ja schon vorgeschlagen. Außerdem kann man sie auch so aktivieren, dass nur neue DS geprüft werden. Um nur mal ein Beispiel zu nennen. Was das bedeutet und wie es Dir in die Hacken läuft ist klar.

Als Ansatz zu dem gelinkten View mit den Ref Constraints dennoch folgender Vorschlag. Bau basierend darauf ein Connect by Prior Select, dass die Tabellen hierarchisch ausspuckt. Vielleicht sieht das Ergebnis so einladend aus, dass Du es gleich so importierst. Vermutlich wirst Du es aber irgendwie zu einer festen Reihenfolge bereinigen müssen.

Wie schon gesagt wurde, selbst die richtige Reihenfolge garantiert gar nichts.
Constraints aus- und einschalten ist sicher effizienter.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#6

AW: Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 26. Apr 2012, 00:49
Stringliste A mit Namen aller 3000 Tabellen.
Stringliste B mit Namen aller kopierten Tabellen (zu Anfang leer)

Code:
repeat
  1. Tabellennamen aus Liste A rausgreifen (Suchkandidat)

  Prüfen, ob es im View einen Parent zum Suchkandidat gibt und dabei aber die Liste B beachten
  falls ja: den Tabellenname ans Ende der Stringliste befördern, der Name der Parenttabelle wird zu deinem neuen Suchkandidaten
  falls nein: Tabellename von Liste A nach Liste B verschieben.
until Liste A is empty
Die Liste B enthält nun die Tabellennamen in der gewünschten Reihenfolge.

Geändert von sx2008 (26. Apr 2012 um 00:53 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#7

AW: Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 26. Apr 2012, 01:03
Was machst du denn, wenn eine Tabelle Fremdschlüsselbeziehung zu sich selbst hat?
Oder es allgemein Kreise in den Beziehungen gibt?

Davon abgesehen:
1) und 3) sind sehr ähnlich: Es sind Tabellen die zu keiner anderen Tabelle eine Fremdschlüsselbeziehung hat ("Quellen").
Wenn du die Tabellen ordnen willst, würde ich das aufsteigend nach dem maximalen Abstand zu einer Quelle tun.
Zu jeder Tabelle hat jede referenzierte Tabelle muss einen kleineren maximalen Abstand zu einer Quelle haben. Dh. wenn du die Tabellen in dieser Reihenfolge erstellst, sind immer alle Voraussetzungen erfüllt.
Mithilfe von Rekursion und Aggregatsfunktionen (max) sollte es das in SQL möglich sein.

Das funktioniert natürlich nur, wenn es keine Kreise gibt (ansonsten geht der maximale Abstand zur Quelle in einem Kreis gegen unendlich).

Geändert von BUG (26. Apr 2012 um 01:38 Uhr)
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.737 Beiträge
 
Delphi 6 Enterprise
 
#8

AW: Reihenfolge beim einspielen von Tabellen ermitteln

  Alt 26. Apr 2012, 09:42
Hallo zusammen und danke für die Vorschläge. Vllt. nochmal zum Hintergrund: Es gab einen Dump einer DB in eine .sql Datei, die nun alle Tabellen, samt Datentypen und Daten untereinandergeschrieben enthält, die Tabellen alphabetisch.

Aufgabe (für Azubi) war nun diese Datei, die ja eigentlich nur eine Textdatei ist so zu sortieren, das die Tabellen in einer Reihenfolge kommen, damit es nicht knallt.

Habe das nun so gelöst, dass ich die Textdatei zerlegt habe in einzelne Dateien für jede Tabelle, wobei Tabellen ohne Daten gleich weggelassen wurden. Das war Programmteil 1.

Dann habe ich die benötigte Reihenfolge ermittelt (Ziel dieses Threads, s.u.) und die Tabellendateien in der Reihenfolge wieder zu einer zusammengefasst.

Diese Datei kann nun mit einem entsprechenden Tool der Software (für die diese Datenbank da ist) importiert werden. Das war die Vorgabe, es muss dieses Tool genutzt werden und die Tabellen müssen in der Reihenfolge passen, sonst kann das Tool das nicht.

Das direkte reinschreiben in die DB, z.B. mit SQL-Loader o.ä., wäre möglich, mit de- und anschl. reaktivierung der Constraints, bzw. dem Oracle-SQL-Loader ist das sowieso egal, der paukt die Daten ohne Rücksicht auf Verluste in die DB, mein ich. Aber das wollte wohl die Fachabteilung nicht, die wollten den Import-Assi nutzen.

------------
Back to Topic:
Ich hab es wie im Anfang des Threads geplant gemacht:
Erst alle Parent-Tabellen, die nicht selber Child-Tabellen sind.
Dann alle Child-Tabellen.
Dann alle restl. Tabellen.

Dabei hab ich für Punkt 2 zwei Listen erstellt: Eine mit Childtabellen und eine leere. In die leere zunächst die Parenttabellen aus Punkt 1 geschrieben.
Dann bin ich die Liste der Childtabellen durchgegangen und hab für jedes Child eine Rekursive-Funktion aufgerufen, etwa so:

Delphi-Quellcode:
procedure AddTabToList(Tabname:String)
var
  t:TStringlist;
  i:Integer;
begin
if not AlreadyInList(Tabname) then
  begin
  t:=TStringlist.create;
  GetParents(Tabname,t); //schreibt in t alle Parents von Tabname
  for i:=0 To t.Count-1 do
    AddTabToList(t.Strings[i]);
  AddToList(Tabname);
  t.free;
  end
end;
Damit hat es funktionert, weil es keine zirkulären abhängigkeiten in den Tabellen-Constraints gab. Hätte es welche gegeben wäre das in die Hose gegangen.
Ralph

Geändert von Jumpy (26. Apr 2012 um 09:45 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz