AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Textdatei > 500 MB für DB vorbereiten

Ein Thema von OG Karotte · begonnen am 2. Jan 2008 · letzter Beitrag vom 4. Jan 2008
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von himitsu
himitsu

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

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 13:42
das #12 ist da immer in einer eigenen Zeile?
(oder maximal am Ende einer Datensatzzeile, also vor einem Zeilenwechsel bzw hinter einem Feldnamen)


zwei ganz einfache Beispiele zum Auslesen aller Feldnamen:
! Groß-/Kleinschreibung wird beachtet

Delphi-Quellcode:
var F: TextFile;
  Feldnamen: Array of String;
  S: String;
  B: Boolean;
  i: Integer;
begin
  AssignFile(F, {Dateiname});
  Reset(F1);
  Feldnamen := nil;
  while not EOF(F) do begin
    ReadLn(F, S);
    i := Pos(':', S);
    if i = 0 then Continue;
    S := Trim(Copy(S, 1, i - 1));
    B := True;
    for i := High(Feldnamen) downto 0 do
      if Feldnamen[i] = S then B := False;
    if B then begin
      i := Length(Feldnamen);
      SetLength(Feldnamen, i + 1);
      Feldnamen[i] := S;
    end;
  end;
  CloseFile(F);
end;
Delphi-Quellcode:
var F: TextFile;
  Feldnamen: TStringList;
  S: String;
  i: Integer;
begin
  AssignFile(F, {Dateiname});
  Reset(F1);
  Feldnamen := TStringList.Create;
  Feldnamen.Duplicates := dupIgnore;
  while not EOF(F) do begin
    ReadLn(F, S);
    i := Pos(':', S);
    if i = 0 then Continue;
    S := Trim(Copy(S, 1, i - 1));
    Feldnamen.Add(S);
    end;
  end;
  CloseFile(F);
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#12

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 13:59
Aber das ist doch popeleinfach...

Delphi-Quellcode:
While not MyTextFile.Eof do begin
  MyTable.Append;
  While GetNextField(MyTextFile, sFieldName, sFieldContents) do
    MyTable[sFieldName].AsString := sFieldContents
  MyTable.Post;
End;
Die Funktion 'GetNextField' liest die nächste nicht-leere Zeile vom MyTextFile ein und liefert TRUE, wenn es sich um einen Feldinhalt handelt (und dann in 'sFieldName' den Feldnamen und in 'sFieldContents' den Inhalt), oder FALSE sonst.

Das Langsame hier ist:
    MyTable[sFieldName].AsString := sFieldContents Das bekommt man mit einer kleinen Hashmap wesentlich schneller hin. Diese Map liefert zum Feldnamen den Feldindex, sodaß man dann direkt in die entsprechende Spalte schreiben kann.

Selbst wenn das Einlesen 30 min dauert, ist das immer noch kürzer, als umständlich nach einer performanten Lösung zu suchen. Was hast Du davon, wenn Du in 5 Tagen eine solche implementiert hast?

[edit]... Wenn die Tabelle noch nicht existiert bzw. die Gesamtmenge der Feldnamen noch nicht bekannt ist, würde ich die Datei einmal durchscannen, um alle Feldnamen zu erhalten. Damit wird dann die Tabelle erzeugt bzw. ggf. erweitert. Im laufenden Betrieb geht das nicht so einfach.

Du kannst aber auch komplett auf ein TDataset verzichten und nur mit SQL arbeiten. Dazu müsste man aber wissen, ob Access auch DDL kennt, also CREATE / ALTER TABLE, um ggf neue Feldnamen an die Tabelle anzubepseln. [/edit]
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
OG Karotte
(Gast)

n/a Beiträge
 
#13

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 19:30
Zitat von himitsu:
das #12 ist da immer in einer eigenen Zeile?
(oder maximal am Ende einer Datensatzzeile, also vor einem Zeilenwechsel bzw hinter einem Feldnamen)
Jede Zeile enthält einen Feldnamen und den Feldinhalt getrennt voneinander durch ': ' (Doppelpunkt und 2 Leerzeichen)
Die Zeile wird durch CRLF abgeschlossen.
Der Datensatz wird durch mindestens eine Leerzeile gefolgt von 0x0c in einer extra Zeile vom nächsten Datensatz getrennt.

@himitsu: Beide Deiner Routinen sind im Prinzip schnell (auf meinem Testrechner so um die 40 - 50 Sekunden) , ABER
damit ist das Prog optisch eingefroren. Füge ich nun ein Application.ProcessMessage hinzu um z.B. die FilePos oder einen Fortschrittsbalken anzuzeigen, bricht die Performance total zusammen und ich liege in etwa bei der Zeit wie mit meiner kleinen Testroutine. (na ja stimmt nicht ganz, deine ist immer noch deutlich schneller )
Also werde ich in dieser Richtung mal weitertesten und mich von Streams (mein Ansatz) fernhalten...


@alzaimar:

Zitat:
Aber das ist doch popeleinfach...
Danke!!!, Danke!!!, Danke!!!...(Welcher Smiley steht doch noch gleich für beleidigt sein ??? )

Zitat:
Wenn die Tabelle noch nicht existiert bzw. die Gesamtmenge der Feldnamen noch nicht bekannt ist, würde ich die Datei einmal durchscannen, um alle Feldnamen zu erhalten.
Da habe ich ja schon das erste Geschwindigkeitsprob.

Zitat:
Delphi-Quellcode:
While not MyTextFile.Eof do begin
  MyTable.Append;
  While GetNextField(MyTextFile, sFieldName, sFieldContents) do
    MyTable[sFieldName].AsString := sFieldContents
  MyTable.Post;
End
Gedanklich schwebte mir das ebenso vor. Abgeschreckt hatte mich aber nun schon der erste Testlauf um die Feldnamen auszulesen. Mit der besten bzw. schnellsten Routine (bei Verwendung von Streams) lag ich in etwa bei 20 Minuten.

Zitat:
Selbst wenn das Einlesen 30 min dauert, ist das immer noch kürzer, als umständlich nach einer performanten Lösung zu suchen. Was hast Du davon, wenn Du in 5 Tagen eine solche implementiert hast?
Also, erstens: Innerliche Befriedigung, zweitens habe ich irgendwo im Netz einen Converter gefunden, der die Daten "ruckzuck" in eine *.CSV Datei schreibt (allerdings berücksichtigt dies Tool nur die Feldbezeichner des ersten Datensatzes) und dort müsste man doch auch hinkommen, zumal der Standardanwender eh immer unter Zeitdruck ist und ihm nichts schnell genug geht , und drittens brauche ich im Augenblick einfach ein Erfolgserlebnis (gewöhne mir gerade das Rauchen ab)...
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#14

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 20:08
ich gehe mal davon aus, dass du nicht alle felder abspeichern willst (z. B. SystemABDocUnID: HexID) und wohl auch nicht alle daten, die in dem 1/4 geändert wurden verwerfen.

dann müsstest du dir erst mal aussuchen, welche daten du überhaupt den anwender zeigen willst und in welcher tabellenstruktur du das ablegen möchtest. wenn du das gemacht hast, ist die hauptarbeit eigentlich schon erledigt. du kennst die felder, die tabellen und die namen aus Lotus notes. dann bruchst nur noch einmal durchgehen, wenn der name auftritt entsprechend zuweisen und einmal abspeichern. das geht ruck-zuck. ggf. müsstest du da noch prüfen ob die einträge schon vorhanden sind nach dem schema if not exists then insert else update.

das endekennzeichen ist ja #12 und von daher weisst prima wenn 'n neuer datensatz beginnt.

schon mal darüber nachgedacht?
  Mit Zitat antworten Zitat
OG Karotte
(Gast)

n/a Beiträge
 
#15

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 21:17
Zitat von grenzgaenger:
ich gehe mal davon aus, dass du nicht alle felder abspeichern willst (z. B. SystemABDocUnID: HexID)
Korrekt, alle Felder sollen nicht importiert werden. Jedoch ein Auswahl, über die der Nutzer selbst entscheidet. Insbesondere über die Felder, die NICHT zu einem Standardexport (in der LoNo DB sind auch benutzerdefinierte Felder (deswegen u.a. auch die Unterschiede der einzelnen Datensätze) vorhanden) gehören, soll der Nutzer selbst entscheiden können.

Zitat:
dann müsstest du dir erst mal aussuchen, welche daten du überhaupt den anwender zeigen willst und in welcher tabellenstruktur du das ablegen möchtest.
Im Prinzip wird es wahrscheinlich nur eine Tabelle geben, in die die Daten überführt werden müssen...

Zitat:
das geht ruck-zuck.
Alles Relativ (s.o.)

Zitat:
ggf. müsstest du da noch prüfen ob die einträge schon vorhanden sind nach dem schema if not exists then insert else update
So soll es bei den Updates geschehen. Wobei ich dort erstmal prüfen will, was länger dauert bzw. einfacher geht:
Ein Delta einspielen oder einfach mit dem Gesamtabzug überschreiben.
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#16

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 22:50
der gesamtabzug mit einem vorherigen drop-table ist mit sicherheit schneller. die frage ist nur, ob du das wirklich willst...

ansonsten, sind die benutzerdefinierten felder normal in der lokalen db, nicht in der server db. wie siehts denn aus, woher kommen die daten... und wie sollen sie eingespielt werden... jeder benutzer spielt im quartal das selbe ein? find ich persönlich nicht wirklich sinnvoll. ausserdem trau ich den wenigsten usern zu, dass sie etwas sinnvolles auswählen...

wäre es da nicht sinnvoller die daten zentral einzuspielen mit einem superset an daten, die für alle gleich sind und dann die einzelnen user dann die daten zusammenstreichen lassen, welche sie gerne sehen würden?


PS: zum einspielen gibt es ja auch mehrere möglichkeiten, z.b. erst mal 'ne tabelle mit 60 oder noch mehr feldern aufmachen, die namen dann zum schluss assigen und die restliche dann zu droppen oder unbenutzt stehen zu lassen, oder einfach alles in 'n blob übernehmen ...

ausserdem, wenn du richtig hingesehen hast, hast du in deinem beispiel flatfile wiederholungszeilen. wie willst mit dennen umgehen ... auch alles 'in 'n blob oder so, dass man danach suchen kann? im zweiten fall, brauchst du 'ne detailtabelle, damit du das ordentlich abhandeln kannst. hoffe solche kleinigkeiten hast nicht übersehen und sind bereites in deinem konzept integriert.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#17

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 22:57
Zitat von OG Karotte:
Zitat:
Wenn die Tabelle noch nicht existiert bzw. die Gesamtmenge der Feldnamen noch nicht bekannt ist, würde ich die Datei einmal durchscannen, um alle Feldnamen zu erhalten.
Da habe ich ja schon das erste Geschwindigkeitsprob.
Das suchen in einer Feldliste, ob der Feldname schon bekannt ist, dürfte hier der Flaschenhals sein. Daher ==> Hashmap (Such mal nach einer 'TStringDictionary'. Die ist von mir und sollte schnell genug sein).

Zitat von OG Karotte:
Also, erstens: Innerliche Befriedigung, zweitens habe ich irgendwo im Netz einen Converter gefunden, der die Daten "ruckzuck" in eine *.CSV Datei schreibt (allerdings berücksichtigt dies Tool nur die Feldbezeichner des ersten Datensatzes) und dort müsste man doch auch hinkommen, zumal der Standardanwender eh immer unter Zeitdruck ist und ihm nichts schnell genug geht , und drittens brauche ich im Augenblick einfach ein Erfolgserlebnis (gewöhne mir gerade das Rauchen ab)...
Aha. Das Übliche also. Aber der Ruckzuck-Converter schummelt ja, denn das kann ich auch.

Hmmm. Du sagst, Du hättest 180.000 Datensätze mit jeweils ca. 20-40 Feldern. Also hmmm, ich denke, das geht in 1-2 Minuten (Feldnamen ermitteln).

Was ich daran so dämlich finde, ist jedoch, das die Gesamtmenge der Feldnamen nicht definiert sind. Nun gut.

Mal sehen, wenn mir morgen langweilig ist, setz ich mich mal ran.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
OG Karotte
(Gast)

n/a Beiträge
 
#18

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 23:56
Zitat von alzaimar:
Hmmm. Du sagst, Du hättest 180.000 Datensätze mit jeweils ca. 20-40 Feldern. Also hmmm, ich denke, das geht in 1-2 Minuten (Feldnamen ermitteln).
...
Das suchen in einer Feldliste, ob der Feldname schon bekannt ist, dürfte hier der Flaschenhals sein.
Yup, sowohl mit den "direkten" Routinen von himitsu als auch von hallo du durchlaufen das ganze in wenigen Minuten (Meine Streammethode brauchte da deutlich länger). Aber es scheint tatsächlich das Filtern der Mehrfachvorkommen der Feldnamen UND die Aktualisierung der Bildschirmausgabe (der Nutzer soll ja sehen, das etwas passiert) die Einbussen in der Geschwindigkeit bringen.

Dein TStringDictionary schaue ich mir mal morgen (upps schon so spät) heut nachmittag an.

Zitat von alzaimar:
Was ich daran so dämlich finde, ist jedoch, das die Gesamtmenge der Feldnamen nicht definiert sind. Nun gut.
Tja, das ist ja das Blöde da hab ich aber null Einfluss drauf; Viele Admin's verderben den Brei äh die DB...

Zitat von grenzgaenger:
der gesamtabzug mit einem vorherigen drop-table ist mit sicherheit schneller. die frage ist nur, ob du das wirklich willst...
Warum nicht ?!?

Zitat von grenzgaenger:
ansonsten, sind die benutzerdefinierten felder normal in der lokalen db, nicht in der server db. wie siehts denn aus, woher kommen die daten... und wie sollen sie eingespielt werden...
Also den Abzug des Textfiles mach ich selbst (aber dort sind halt ALLE Daten der zentralen DB enthalten (auch die benutzerdefinierten Felder eines x-beliebigen Admin's an einem x-beliebigen Ort). Beim Abzug (Export) gibt es aber nur die Möglichkeit Alles Exportieren oder nur (händisch) ausgewählte Dokumente.

Zitat von grenzgaenger:
jeder benutzer spielt im quartal das selbe ein? find ich persönlich nicht wirklich sinnvoll. ausserdem trau ich den wenigsten usern zu, dass sie etwas sinnvolles auswählen...
Stimmt. Das sollte ich vielleicht nochmal überdenken

Zitat von grenzgaenger:
wäre es da nicht sinnvoller die daten zentral einzuspielen mit einem superset an daten, die für alle gleich sind und dann die einzelnen user dann die daten zusammenstreichen lassen, welche sie gerne sehen würden?
Dito (s.o.)
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#19

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 3. Jan 2008, 23:57
Zitat von alzaimar:
Was ich daran so dämlich finde, ist jedoch, das die Gesamtmenge der Feldnamen nicht definiert sind. Nun gut.
klar ist diese definiert. bei LN server datenbanken durch den administrator. die anderen können normal nur lokal abgelegt werden. aber da steht die antwort noch aus.

was mir schleierhaft ist, was das progy machen soll, wenn der inhalt der db nicht defniert ist... taugt das ja noch nicht mal als adressliste...

@alzaimar: was steht dagegen 'ne kontenform zu verwendeten, so wie der textoutput...
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#20

Re: Textdatei > 500 MB für DB vorbereiten

  Alt 4. Jan 2008, 00:04
Zitat von OG Karotte:
Zitat von grenzgaenger:
ansonsten, sind die benutzerdefinierten felder normal in der lokalen db, nicht in der server db. wie siehts denn aus, woher kommen die daten... und wie sollen sie eingespielt werden...
Also den Abzug des Textfiles mach ich selbst (aber dort sind halt ALLE Daten der zentralen DB enthalten (auch die benutzerdefinierten Felder eines x-beliebigen Admin's an einem x-beliebigen Ort). Beim Abzug (Export) gibt es aber nur die Möglichkeit Alles Exportieren oder nur (händisch) ausgewählte Dokumente.
gut, das ist ja kein problem, wenn alle felder aus der datenbank. aber um sie sinnvoll weiterzubearbeiten, denke ich, dass es sinnvoll ist, nur die sinnvollen felder in eine andere datenbank einzuspielen. hierfür könnt man ja 'ne kleine felddefinition in die einleseroutine mit aufnehmen... welche dann die sinnvollen felder filtert.

ausserdem müssten natürlich noch entsprechende plausi prüfungen erfolgen. z.b. welche felder unbedingt gefüllt werden müssen und welche leer sein dürfen ..

denke, alles in allen, ist das kein ad-hoc projekt. welches in 'ner 1/2 stunde eingeführt ist... da sollt man schon etwas drüber nachdenken, wie man das am sinnvollsten macht. so dass man das dann nicht jedes quartal umschreiben darf ...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 05:49 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