Filter für enthaltene Fields in NTX - Indexdatein
Moderator: Moderatoren
Filter für enthaltene Fields in NTX - Indexdatein
Hi,
kennt jemand eine effiziente Möglichkeit, aus den Ergebnissen von OrdKey() und OrdFor() (NTX - Index) die darin enthalten Field Namen der Datenbank herauszufiltern? Sinn und Zweck dieser Funktionalität ist es, bereits im Vorfeld eines Schreibzugriffes auf die Datenbank zu entscheiden, welche der vorhanden Indexdateien geöffnet werden müssen (es ist hier schon bekannt, zu welchem Field es eine Änderung gegeben hat).
Mit freundlichen Grüßen
Joachim Krause
kennt jemand eine effiziente Möglichkeit, aus den Ergebnissen von OrdKey() und OrdFor() (NTX - Index) die darin enthalten Field Namen der Datenbank herauszufiltern? Sinn und Zweck dieser Funktionalität ist es, bereits im Vorfeld eines Schreibzugriffes auf die Datenbank zu entscheiden, welche der vorhanden Indexdateien geöffnet werden müssen (es ist hier schon bekannt, zu welchem Field es eine Änderung gegeben hat).
Mit freundlichen Grüßen
Joachim Krause
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Filter für enthaltene Fields in NTX - Indexdatein
hi,
beim aufbau des Index ja "+" benutzt ...
Dateien die zu eine DBF gehören ZUSAMMEN auf. Danach kannst du
dann mit SET ORDER ( DbSetOrder() ) den "kontrollierenden" Index
einstellen.
Wenn du z.b. "nur" 1 von 3 Index Datein aufmachst und ein "update"
darauf ausführst und nicht auf die beiden anderen so wirst du irgendwann
einen 1210 (Cl*pper) Fehler beim öffnen der DBF bekommen.
gruss by OHR
Jimmy
es sind doch nur cString die zu zurück bekommst, Als "Trenner" hast duKrause hat geschrieben: kennt jemand eine effiziente Möglichkeit, aus den Ergebnissen von OrdKey() und OrdFor() (NTX - Index) die darin enthalten Field Namen der Datenbank herauszufiltern?
beim aufbau des Index ja "+" benutzt ...
sorry aber da muss ich mal einharken : Man mach IMMER ALLE IndexKrause hat geschrieben: Sinn und Zweck dieser Funktionalität ist es, bereits im Vorfeld eines Schreibzugriffes auf die Datenbank zu entscheiden, welche der vorhanden Indexdateien geöffnet werden müssen (es ist hier schon bekannt, zu welchem Field es eine Änderung gegeben hat).
Dateien die zu eine DBF gehören ZUSAMMEN auf. Danach kannst du
dann mit SET ORDER ( DbSetOrder() ) den "kontrollierenden" Index
einstellen.
Wenn du z.b. "nur" 1 von 3 Index Datein aufmachst und ein "update"
darauf ausführst und nicht auf die beiden anderen so wirst du irgendwann
einen 1210 (Cl*pper) Fehler beim öffnen der DBF bekommen.
gruss by OHR
Jimmy
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1930
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Hi Jimmy,
wir haben unsere Programme etwas anders als "Normal" aufgebaut. Prinzipell "öffnen" wir nur Datenbanken / Dateien wenn wir einen Zugriff benötigen.
Im Klartext, eine Applikation unterhält im "Ruhezustand" keine verbindung zum Server. Ein internes dynisch aufgebautes Dictionary sowie ein ausgeklügeltes Cachesystem garantieren ein problemloses Arbeiten mit allen möglichen Datenquellen (DBF, ASCII, ADS, SQL etc.) Gesteuert wird dieses Sytem allein nur über im Dictionary verwalteten ALIAS-Namen. Realisiert wird das ganze durch eine speziell für diesen Aufgabenbereich entwickelte DLL.
Für alle Lesezugriffe werden zum Bsp. die Datenbanken Readonly / Shared geöffnet, hierbei wird nur noch der aktive Index mitgeöffnet. Dieses System arbeitet bei uns seit der Version XBase 1.8.2 problemlos.
Für alle Schreibzugriffe werden die Datenbanken Exclusive geöffnet. Hier machen wir im Moment noch alle INDEX-Dateien auf. Dieses möchte ich jedoch dahin ändern, dass ich nur noch die notwendigen Indexdateien aufmache.
Mitt diesem Verfahren arbeiten wir derzeit mit ca. 124 Arbeitsplätzen gleichzeiteig in ein und dem selben Datenbestand.
Mit freundlichen Grüßen
Joachim Krause
wir haben unsere Programme etwas anders als "Normal" aufgebaut. Prinzipell "öffnen" wir nur Datenbanken / Dateien wenn wir einen Zugriff benötigen.
Im Klartext, eine Applikation unterhält im "Ruhezustand" keine verbindung zum Server. Ein internes dynisch aufgebautes Dictionary sowie ein ausgeklügeltes Cachesystem garantieren ein problemloses Arbeiten mit allen möglichen Datenquellen (DBF, ASCII, ADS, SQL etc.) Gesteuert wird dieses Sytem allein nur über im Dictionary verwalteten ALIAS-Namen. Realisiert wird das ganze durch eine speziell für diesen Aufgabenbereich entwickelte DLL.
Für alle Lesezugriffe werden zum Bsp. die Datenbanken Readonly / Shared geöffnet, hierbei wird nur noch der aktive Index mitgeöffnet. Dieses System arbeitet bei uns seit der Version XBase 1.8.2 problemlos.
Für alle Schreibzugriffe werden die Datenbanken Exclusive geöffnet. Hier machen wir im Moment noch alle INDEX-Dateien auf. Dieses möchte ich jedoch dahin ändern, dass ich nur noch die notwendigen Indexdateien aufmache.
Mitt diesem Verfahren arbeiten wir derzeit mit ca. 124 Arbeitsplätzen gleichzeiteig in ein und dem selben Datenbestand.
Mit freundlichen Grüßen
Joachim Krause
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo,
solange nur gelesen wird, braucht man nicht alle Indexdateien öffnen,
beim Schreiben wird es aber gefährlich !
Wer will wirklich beurteilen, ob ein replace Indexrelevant ist oder nicht.
Jimmy hat mit seinem Kommentar auf jeden Fall recht, solange es sich nicht nur um readonly Dateien handelt.
solange nur gelesen wird, braucht man nicht alle Indexdateien öffnen,
beim Schreiben wird es aber gefährlich !
Wer will wirklich beurteilen, ob ein replace Indexrelevant ist oder nicht.
Jimmy hat mit seinem Kommentar auf jeden Fall recht, solange es sich nicht nur um readonly Dateien handelt.
Gruß
Hubert
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21189
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi,
nur mal ein kurzer Einwurf. Ist es nicht so, das bei geöffneten Indexdateien generell irgendwie geschrieben wird, wenn REPLACED wird, egal ob der Index geändert wird oder nicht? Ich meine ich habe es mal gehört und irgendwie im Debugger nachgesehen, wenn man z.B. eine Funktion in einem Index hat. Deshalb sollte man schon alle Indexdateien auf haben.
nur mal ein kurzer Einwurf. Ist es nicht so, das bei geöffneten Indexdateien generell irgendwie geschrieben wird, wenn REPLACED wird, egal ob der Index geändert wird oder nicht? Ich meine ich habe es mal gehört und irgendwie im Debugger nachgesehen, wenn man z.B. eine Funktion in einem Index hat. Deshalb sollte man schon alle Indexdateien auf haben.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo Manfred,
also erstens geht REPLACE nicht bei READONLY Dateien, somit habe ich ja empfohlen alle Indexe zu öffnen, ob immer etwas darein geschrieben wird, kann man in den Eigenschaften sehen. Wenn im Explorer die Zeiten des letzten Speicherns von Indexdateien zueinander und der DBF abweichen, dann trifft die Aussage nicht zu. Ohne eine nötige Änderung in eine Indexdatei zu schreiben wäre aber Zeitverschwendung, das kann ich mir nicht vorstellen. LUpdate() bezieht sich nur auf die DBF.
also erstens geht REPLACE nicht bei READONLY Dateien, somit habe ich ja empfohlen alle Indexe zu öffnen, ob immer etwas darein geschrieben wird, kann man in den Eigenschaften sehen. Wenn im Explorer die Zeiten des letzten Speicherns von Indexdateien zueinander und der DBF abweichen, dann trifft die Aussage nicht zu. Ohne eine nötige Änderung in eine Indexdatei zu schreiben wäre aber Zeitverschwendung, das kann ich mir nicht vorstellen. LUpdate() bezieht sich nur auf die DBF.
Gruß
Hubert
Hubert
Es könnte doch funktionieren ...
Hi Hubert,
du schreibst:
Diesbezüglich habe ich schon entsprechende Test durchgeführt, so lange man kein Update auf Indexrelevante Fields / Colums durchführt, kann man problemlos die (DBF) Datenbanken exclusive öffnen und Daten zurückschreiben ohne die Indexdateien ebenfalls öffnen zu müssen. Ein simples Beispiel wäre eine Kundendatenbank in der der Umsatz geändert wird und wobei der Umsatz nicht Indexrelevant ist.
In der Phase der Erstinitialisierung unseres dynamischen dictionary öffne ich beim ersten Zugriff alle Indexdateien, in diesem Zusammenhang könnte ich also aus den Rückgabewerten von OrdKey() und OrdFor() eine diesbezügliche „Fieldliste“ je Indexfile erstellen und abspeichen.
Mit freundlichen Grüßen
Joachim Krause
[/quote]
du schreibst:
wie bereits vermerkt ...Jimmy hat mit seinem Kommentar auf jeden Fall recht, solange es sich nicht nur um readonly Dateien handelt.
... kenne ich die Updateanforderung bezogen auf das einzelne Field /Column eines Records. Ich schreibe Prinzipiell nur nach einem Verify recordunabhängig über primary key zurück, kenne also SOLL und IST.(es ist hier schon bekannt, zu welchem Field es eine Änderung gegeben hat).
Diesbezüglich habe ich schon entsprechende Test durchgeführt, so lange man kein Update auf Indexrelevante Fields / Colums durchführt, kann man problemlos die (DBF) Datenbanken exclusive öffnen und Daten zurückschreiben ohne die Indexdateien ebenfalls öffnen zu müssen. Ein simples Beispiel wäre eine Kundendatenbank in der der Umsatz geändert wird und wobei der Umsatz nicht Indexrelevant ist.
In der Phase der Erstinitialisierung unseres dynamischen dictionary öffne ich beim ersten Zugriff alle Indexdateien, in diesem Zusammenhang könnte ich also aus den Rückgabewerten von OrdKey() und OrdFor() eine diesbezügliche „Fieldliste“ je Indexfile erstellen und abspeichen.
Mit freundlichen Grüßen
Joachim Krause
[/quote]
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Das ist einfach nicht richtig. Indexe werden aktualisiert, wenn sich die Satzreihenfolge oder -anzahl ändert (z.B. durch DbPack, DbAppend, mit DbDelete nur dann, wenn der Index die Kondition FOR !Deleted() hat), oder wenn sie inhaltlich betroffen sind. Wenn ich einen Index auf das Feld NAME habe und pausenlos VORNAME ändere, brauche ich den Index auf NAME nicht. Er ändert sich nicht. Und einen Korruptionsfehler kann man, wenn man das sorgfältig macht, auf diese Art auch nicht erzeugen.Wenn du z.b. "nur" 1 von 3 Index Datein aufmachst und ein "update"
darauf ausführst und nicht auf die beiden anderen so wirst du irgendwann
einen 1210 (Cl*pper) Fehler beim öffnen der DBF bekommen.
@Manfred: Indexdateien werden normalerweise (DBFNTX) bei jeder Dateioperation - suchen, bewegen, ersetzen - vollständig gelockt (ro), aber wirklich nur für eine mikroskopisch kurze Zeit. Seit der 1.9 gibt es Extended Locking für Indexe, wobei dann tatsächlich nur betroffene Sätze gesperrt werden, aber auch bei allen Operationen.
Herzlich,
Tom
Tom
- Manfred
- Foren-Administrator
- Beiträge: 21189
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi Tom,
ich lasse mich gerne belehren. Es war dann eine falsche Info, oder Beobachtung. Aber besser so als andersherum.
ich lasse mich gerne belehren. Es war dann eine falsche Info, oder Beobachtung. Aber besser so als andersherum.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Wie ein NTX-Index (Clipper; Alaska hat da ein bißchen dran rumgeschraubt, aber nicht essentiell) aufgebaut ist, kann man hier nachlesen:
http://www.wotsit.org/download.asp?f=ntx
http://www.wotsit.org/download.asp?f=ntx
Herzlich,
Tom
Tom
- Martin Altmann
- Foren-Administrator
- Beiträge: 16511
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 111 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Und ein kurzer Einwurf von mir:
Es müssen alle betroffenen Indexdateien geöffnet sein, sofern ein in den Indexen vorhandenes Schlüsselfeld in der Datenbank geändert wird!
Den Beweis habe ich bereits hier im Forum erbracht!
Sind die Indexdateien zum Zeitpunkt der Änderungen nicht geöffnet, ist ist ein reindex nötig!
Viele Grüße,
Martin
Es müssen alle betroffenen Indexdateien geöffnet sein, sofern ein in den Indexen vorhandenes Schlüsselfeld in der Datenbank geändert wird!
Den Beweis habe ich bereits hier im Forum erbracht!
Sind die Indexdateien zum Zeitpunkt der Änderungen nicht geöffnet, ist ist ein reindex nötig!
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9361
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 101 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Hallo, Martin.
Genau darum geht es Joachim ja. Er will ggf. Schlüsselfelder ersetzen und dafür nur diejenigen Indexdateien öffnen, die betroffen sind.
@Joachim: Aber ganz habe ich Deine Frage nicht verstanden.
Wenn Du jetzt herausbekommen willst, welche Indexe geöffnet werden müssen, wenn ein bestimmtes Feld geupdated wird, mußt Du alle Indexe öffnen:
Damit ist aber nichts gewonnen, Du mußt den Index ja öffnen. Du kannst Dir natürlich auch die Struktur einer NTX-Datei ansehen (siehe oben) und direkt in der Datei nach dem Feldnamen suchen. Aber Du schrubst etwas von wegen Ihr würdet eine Art Repository führen. Was spricht dagegen, solche Informationen dort vorzuhalten?
Genau darum geht es Joachim ja. Er will ggf. Schlüsselfelder ersetzen und dafür nur diejenigen Indexdateien öffnen, die betroffen sind.
@Joachim: Aber ganz habe ich Deine Frage nicht verstanden.
Code: Alles auswählen
USE KUNDEN
INDEX ON name+vorname TO KUNDEN
SET INDEX TO KUNDEN
? OrdKey() // Antwort: name+vorname
? IndexKey() // Kompatiblitätsfunktion, gleiche Antwort
Code: Alles auswählen
FOR i := 1 to FCount()
IF Upper(FieldName(i)) $ upper(OrdKey())
* Dieser Feld ist, wenn der Name nicht Teil eines anderen Feldnamens
* ist, im Index
ENDIF
NEXT
Herzlich,
Tom
Tom
Das Problem im einzelnen ...
Hi Tom,
du schriebst:
Die übergeordnete Instanz (zum Bsp. die EXE) registriert die Datenbank und kann dann danach nur über den Alias auf diese Datenbank zugreifen.
Sie weiß von Prinzip danach nicht mehr, um welche Datenbank es sich eigentlich wirklich handelt, der Zugriff ist intern standartisiert. Die EXE (Applikation) greift also auf eine DBF genauso zu wie auf eine Oracle Table.
Es geht mir eigentlich nicht nur um das öffnen oder nicht öffnen von Indexdateien, es geht auch um eine automatische Primary Key Verwaltung ähnlich SQL, das heißt aus UNIQE wird gegebenenfalls ein PRIMARY KEY.
Die Struktur der NTX Indexfile lese ich bereits im Vorfeld aus, es fehlt also der Filter. Indexbedingungen können sehr komplex sein, hier nur ein einfaches Beispiel:
WERK_NR+KUNDENNR+ IIF(EROF,"T","F")+IIF(FREI,"T","F")+IIF(EINST,"T","F")
Mit freundlichen Grüßen
Joachim Krause
du schriebst:
das stimmt von Prinzip her, aber ich öffne alle Index Files (DBF) nur einmal bei der Erstinitialisierung meines internen und temporären (Lebensdauer nur während der Programmlaufzeit) Dictionary. Diese Dictionary beinhaltet alle relevanten Daten zu einer Datenbank (ähnlich wie bei ADS, nur ich verwalte intern alle Datenbanktypen, SOL Table, ASCII - Files etc.)Damit ist aber nichts gewonnen, Du musst den Index ja öffnen.
Die übergeordnete Instanz (zum Bsp. die EXE) registriert die Datenbank und kann dann danach nur über den Alias auf diese Datenbank zugreifen.
Sie weiß von Prinzip danach nicht mehr, um welche Datenbank es sich eigentlich wirklich handelt, der Zugriff ist intern standartisiert. Die EXE (Applikation) greift also auf eine DBF genauso zu wie auf eine Oracle Table.
Es geht mir eigentlich nicht nur um das öffnen oder nicht öffnen von Indexdateien, es geht auch um eine automatische Primary Key Verwaltung ähnlich SQL, das heißt aus UNIQE wird gegebenenfalls ein PRIMARY KEY.
Die Struktur der NTX Indexfile lese ich bereits im Vorfeld aus, es fehlt also der Filter. Indexbedingungen können sehr komplex sein, hier nur ein einfaches Beispiel:
WERK_NR+KUNDENNR+ IIF(EROF,"T","F")+IIF(FREI,"T","F")+IIF(EINST,"T","F")
Mit freundlichen Grüßen
Joachim Krause
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
hi,
Wenn Xbase++ : erinnerst du noch die v.1.3x und die "komischen"
Fehler wenn eine "SKIP" oder "GOTO" Fehler hatte ? Das hatte dann
immer was mit den Index zu tun auch wenn der nicht aktive war.
Im "Prinzip" sollte es zwar so sein, ist es aber unter Xbase++ NICHT !
betroffene. Mach doch mal folgenden Versuch :
USE TEST INDEX N1,N2,N3
so nun REPLACE mal ein FELD was zun Index N2 gehört. Nun schau dir
mal die *.DBF und die *.NTX an. ALLE habe nun die selbe Uhrzeit und
nicht nur die "bearbeitet" Index.
Das ist auch für mich der Hinweis das etwas mit dem Index nicht stimmt
wenn das Datum/Uhrzeit nicht stimmt ... dann ist ein reindex dran.
gruss by OHR
Jimmy
Ist das jetzt auf Cl*pper oder Xbase++ bezogen ?Tom hat geschrieben:Das ist einfach nicht richtig. Indexe werden aktualisiert, wenn sich die Satzreihenfolge oder -anzahl ändert (z.B. durch DbPack, DbAppend, mit DbDelete nur dann, wenn der Index die Kondition FOR !Deleted() hat),Wenn du z.b. "nur" 1 von 3 Index Datein aufmachst und ein "update"
darauf ausführst und nicht auf die beiden anderen so wirst du irgendwann
einen 1210 (Cl*pper) Fehler beim öffnen der DBF bekommen.
Wenn Xbase++ : erinnerst du noch die v.1.3x und die "komischen"
Fehler wenn eine "SKIP" oder "GOTO" Fehler hatte ? Das hatte dann
immer was mit den Index zu tun auch wenn der nicht aktive war.
Ich werde dich ja kaum von deinen Glauben abbrngen lassen.Tom hat geschrieben: oder wenn sie inhaltlich betroffen sind. Wenn ich einen Index auf das Feld NAME habe und pausenlos VORNAME ändere, brauche ich den Index auf NAME nicht. Er ändert sich nicht. Und einen Korruptionsfehler kann man, wenn man das sorgfältig macht, auf diese Art auch nicht erzeugen.
Im "Prinzip" sollte es zwar so sein, ist es aber unter Xbase++ NICHT !
genau DAS meine ich und es ist nicht nur der "führende" Index oder derTom hat geschrieben: @Manfred: Indexdateien werden normalerweise (DBFNTX) bei jeder Dateioperation - suchen, bewegen, ersetzen - vollständig gelockt (ro), aber wirklich nur für eine mikroskopisch kurze Zeit. Seit der 1.9 gibt es Extended Locking für Indexe, wobei dann tatsächlich nur betroffene Sätze gesperrt werden, aber auch bei allen Operationen.
betroffene. Mach doch mal folgenden Versuch :
USE TEST INDEX N1,N2,N3
so nun REPLACE mal ein FELD was zun Index N2 gehört. Nun schau dir
mal die *.DBF und die *.NTX an. ALLE habe nun die selbe Uhrzeit und
nicht nur die "bearbeitet" Index.
Das ist auch für mich der Hinweis das etwas mit dem Index nicht stimmt
wenn das Datum/Uhrzeit nicht stimmt ... dann ist ein reindex dran.
gruss by OHR
Jimmy
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1930
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Hallo,
also nochmal wenn Datenbankeninhalte verändert werden, ändert sich auch der Index. Um Verwirrungen zu vermeiden, packe ich alle Index in eine Indexdatei. Dann brauche ich nicht mehrere Indexdateien zu öffnen.
Dies geschieht folgendermaßen: Beispiel
set index on artnr (feldname) tag "artikel" to "spstamm.cdx"
set index on liefnr (feldname) tag "liefnr" to "spstamm.cdx"
set index on lartnr (feldname) tag "lartnr" to "spstamm.cdx"
Nachher im Programm brauche ich nur nach dem use der spstamm
set index to "spstamm.cdx"
spstamm->(ordSetfocus("artikel")) oder einen anderen Tag-Namen
Somit habe ich immer gewährleistet, daß die CDX-Indexdatei aktuell ist.
also nochmal wenn Datenbankeninhalte verändert werden, ändert sich auch der Index. Um Verwirrungen zu vermeiden, packe ich alle Index in eine Indexdatei. Dann brauche ich nicht mehrere Indexdateien zu öffnen.
Dies geschieht folgendermaßen: Beispiel
set index on artnr (feldname) tag "artikel" to "spstamm.cdx"
set index on liefnr (feldname) tag "liefnr" to "spstamm.cdx"
set index on lartnr (feldname) tag "lartnr" to "spstamm.cdx"
Nachher im Programm brauche ich nur nach dem use der spstamm
set index to "spstamm.cdx"
spstamm->(ordSetfocus("artikel")) oder einen anderen Tag-Namen
Somit habe ich immer gewährleistet, daß die CDX-Indexdatei aktuell ist.
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Filter für enthaltene Fields in NTX - Indexdatein
hi,
wie wäre es dann mit :
gruss by OHR
Jimmy
wenn du für Ordkey() oder Ordfor() Ergebnisse bekommstKrause hat geschrieben: OrdKey() und OrdFor() (NTX - Index)
...
welche der vorhanden Indexdateien geöffnet werden müssen
wie wäre es dann mit :
Code: Alles auswählen
cIndex := OrdName(OrdNumber())
Jimmy
Xbase ändert Indexfile ohne (für mich) erkennbare Logik
Hi,
leider ist es so, dass Xbase die Indexdateien auch ohne sachlichen Grund (Pack, Zap, OrdKey- oder OrdFor - Bedingungsänderung etc.) und ohne (für mich) erkennbare Logik ändern kann bwz. verändert. Was geändert wird, habe ich noch nicht raus gefunden, lediglich das sich die CRC32 – Summe (nicht die Größe und schon gar nicht der sachliche Inhalt) ändert.
Falsch ist auf jeden fall, das ein abweichendes Datum (zur DBF) einen korrupten Index zur folge haben muss, ein profilaktisches Reindex führt also zu einer erhöhten (Netzwerk) Last und zu Performanzverlust. Auf der anderen Seite kann ich auch diejenigen verstehen, die auf „Nummer Sicher“ gehen.
Sensible Daten stellen wir wenn möglich, "Indexfrei" in entsprechend kleinen Datenbanken dar. Hierbei dient das Filesystem quasi als „Hierarchischen Datenmodell“ welches dem Relationalen Datenbanksystem „überlagert“ ist.
Der „selektive" Zugriff erfolgt hier zum Beispiel über (für große Datenbanken ungeeignet / zu langsam):
Joachim Krause
leider ist es so, dass Xbase die Indexdateien auch ohne sachlichen Grund (Pack, Zap, OrdKey- oder OrdFor - Bedingungsänderung etc.) und ohne (für mich) erkennbare Logik ändern kann bwz. verändert. Was geändert wird, habe ich noch nicht raus gefunden, lediglich das sich die CRC32 – Summe (nicht die Größe und schon gar nicht der sachliche Inhalt) ändert.
Falsch ist auf jeden fall, das ein abweichendes Datum (zur DBF) einen korrupten Index zur folge haben muss, ein profilaktisches Reindex führt also zu einer erhöhten (Netzwerk) Last und zu Performanzverlust. Auf der anderen Seite kann ich auch diejenigen verstehen, die auf „Nummer Sicher“ gehen.
Sensible Daten stellen wir wenn möglich, "Indexfrei" in entsprechend kleinen Datenbanken dar. Hierbei dient das Filesystem quasi als „Hierarchischen Datenmodell“ welches dem Relationalen Datenbanksystem „überlagert“ ist.
Der „selektive" Zugriff erfolgt hier zum Beispiel über (für große Datenbanken ungeeignet / zu langsam):
Mit freundlichen GrüßenDbEval({|| AAdd(aArray, RecNo())}, bFor, bWhile, nCount, xRecordID, lRest)
Joachim Krause
... packe ich alle Index in eine Indexdatei.
Hallo Rolf,
du schriebst:
Mit freundlichen Grüßen
Joachim Krause
du schriebst:
Geht man in deinem Fall davon aus, das eine Nummer in der Regel ca. 10 - 18 Stellen hat (auch alphanumerische Syntax möglich) und du 3 verschieden Nummern in einem Index hältst, dann kann es schon mal passieren, das die Indexfile 25% der Größe der DBF - File überschreitet. Eigentlich erfolgt in diesem Fall der Zugriff wahrscheinlich nur über eine der drei Bedingungen und dafür „ziehst“ du die gesamte Indexfile übers Netz … würde ich nicht so machen.also nochmal wenn Datenbankeninhalte verändert werden, ändert sich auch der Index. Um Verwirrungen zu vermeiden, packe ich alle Index in eine Indexdatei. Dann brauche ich nicht mehrere Indexdateien zu öffnen.
Dies geschieht folgendermaßen: Beispiel
set index on artnr (feldname) tag "artikel" to "spstamm.cdx"
set index on liefnr (feldname) tag "liefnr" to "spstamm.cdx"
set index on lartnr (feldname) tag "lartnr" to "spstamm.cdx"
Nachher im Programm brauche ich nur nach dem use der spstamm
set index to "spstamm.cdx"
spstamm->(ordSetfocus("artikel")) oder einen anderen Tag-Namen
Somit habe ich immer gewährleistet, daß die CDX-Indexdatei aktuell ist.
Mit freundlichen Grüßen
Joachim Krause
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1930
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
RE-Alles in einer Indexdatei
Hi Joachim,
sicherlich hast du recht das die CDX-Datei größer als die DBF ist. Aber bei uns haben unsere Kunden nur die wenigsten ein Netzwerk. Die meisten haben einen einzelnen Stand-Alone-PC.
Daher ist dies nicht so dramatisch.
sicherlich hast du recht das die CDX-Datei größer als die DBF ist. Aber bei uns haben unsere Kunden nur die wenigsten ein Netzwerk. Die meisten haben einen einzelnen Stand-Alone-PC.
Daher ist dies nicht so dramatisch.
Hi,
habe mal schnell einen Filter zusammengebastelt, Basis ist eine bereits bestehende Klasse:
Nun die eigentliche Funktion:
Der eigentliche Funktionsaufruf als Test:
So, das wärs erst einmal, werde das Projekt auf jeden Fall zu Ende führen. Falls jemandem ein gravierender Fehler auffällt währe ich für ein Feedback dankbar ...
Mit freundlichen Grüßen
Joachim Krause
habe mal schnell einen Filter zusammengebastelt, Basis ist eine bereits bestehende Klasse:
Code: Alles auswählen
//***********************************************************************
CLASS SYSC0303
//***********************************************************************
EXPORTED:
METHOD StringToArrayWithSeparateString
ENDCLASS
//***********************************************************************
METHOD SYSC0303:StringToArrayWithSeparateString(cExternDaten, cSepareteString, lNoLeerzeile)
//***********************************************************************
LOCAL aReturnArray:=Array(0)
LOCAL cDaten:=cExternDaten, nFound:=0, nDistanc:= 0, cString:=""
IF ! Valtype(cDaten)=="C" .OR. cDaten==""
RETURN Array(0)
ENDIF
IF lNoLeerzeile==NIL .OR. ! Valtype(lNoLeerzeile)=="L"
lNoLeerzeile:=FALSE
ENDIF
nFound:=Rat(cSepareteString,cDaten)
IF nFound = 0
Return AClone({cDaten})
ENDIF
nDistanc:=LEN(cSepareteString)-1
DO WHILE TRUE
nFound:=At(cSepareteString,cDaten)
IF nFound > 0
cString:=AllTrim(SubStr(cDaten,1,(nFound-1)))
IF lNoLeerzeile
IF ! cString==""
AAdd(aReturnArray,cString)
ENDIF
ELSE
AAdd(aReturnArray,cString)
ENDIF
cDaten:=Stuff(cDaten,1,nFound + nDistanc,"")
ELSE
cDaten:=AllTRim(cDaten)
IF lNoLeerzeile
IF Len(cDaten) > 0
AAdd(aReturnArray,cDaten)
ENDIF
ELSE
AAdd(aReturnArray,cDaten)
ENDIF
EXIT
ENDIF
ENDDO
RETURN AClone(aReturnArray)
Code: Alles auswählen
//***********************************************************************
FUNCTION SYS_FieldFilter(cIndexDescriptor, aDbStruct)
//***********************************************************************
STATIC oDummy:= NIL
IF oDummy==NIL
oDummy:= SYSC031H():new()
ENDIF
RETURN oDummy:FieldFilter(cIndexDescriptor, aDbStruct)
//***********************************************************************
CLASS SYSC031H FROM SYSC0303
//***********************************************************************
EXPORTED:
METHOD FieldFilter
ENDCLASS
//***********************************************************************
METHOD SYSC031H:FieldFilter(cIndexDescriptor, aDbStruct)
//***********************************************************************
STATIC aChar2Null:={"+","-","*","/","\","^","%","=","<",">","#","!","$","(",;
")","&",":","@","{","}","[","]",'"',"'",".",".T.",".F.","AND","OR","NOT","|"}
STATIC cCHRN:=CHR(0)
LOCAL iCounter:=0, aDummy:=Array(0), aReturn:=Array(0)
FOR iCounter:=1 TO Len(aChar2Null)
cIndexDescriptor:=StrTran(cIndexDescriptor, aChar2Null[iCounter], cCHRN)
NEXT
cIndexDescriptor:=UPPER(cIndexDescriptor)
aDummy:=::StringToArrayWithSeparateString(cIndexDescriptor,cCHRN,TRUE)
FOR iCounter:=1 TO Len(aDummy)
IF AScan(aDbStruct,{|c| aDummy[iCounter]==c[1]}) !=0
AAdd(aReturn,aDummy[iCounter])
ENDIF
NEXT
RETURN AClone(aReturn)
Code: Alles auswählen
? SYS_FieldFilter(;
"Upper(MITARBNR+MATCHCODE)+AllTrim(STR(_USRLOCK))",;
{{"MITARBNR","C",4,0}, ;
{"KUNDENNR","C",4,0}, ;
{"WERKNUMMER","C",2,0}, ;
{"MATCHCODE","C",8,0}, ;
{"EXTMATCHC","C",8,0}, ;
{"NUMDATTIME","N",16,0}, ;
{"LSNUMMER","C",27,0}, ;
{"_USRNAME","C",4,0}, ;
{"_STANAME","C",15,0}, ;
{"_USRLOCK","N",4,0}})
Mit freundlichen Grüßen
Joachim Krause
CDX -Index immer die bessere Wahl ?
Hallo Rolf,
du schriebst außerdem:
mindestens genauso treffsicher (bedenkt man, wie viel Müller es giebt...).
Mit freundlichen Grüßen
Joachim Krause
du schriebst außerdem:
CDX - Index ist meiner Meinung nach nicht immer die bessere Wahl, bei einer Personalstammdatendatei (DBF) ist ein NTX-Index mit folgender Bedingung:set index to "spstamm.cdx"
spstamm->(ordSetfocus("artikel")) oder einen anderen Tag-Namen
Code: Alles auswählen
UPPER(LEFT(NAME,5)+LEFT(VORNAME,5)+LEFT(ORT,5))
Mit freundlichen Grüßen
Joachim Krause
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hi,
da eine CDX die Texte komprimiert ablegt ist sie auf jeden Fall deutlich kleiner. Auch ist es - meiner Meinung nach - nicht richtig, dass immer die ganze Indexdatei geladen wird, solange nicht alle Datensätze der DBF gelesen werden. Xbase und Clipper ab 5.0 nutzen keine sequenziellen Indexdateien, die nur kleiner sind, sondern nutzen eine Art von Baumstruktur. Egal wie groß meine Indexe bisher waren (je etwa 20 MB bei 200 MB) und egal wie langsam das Netz war, DBSEEK() war immer sehr schnell.
Bei langsamen Leitungen (64KB) dauerte allerdings das Öffnen der DBF mit 3 bis 4 NTX Dateien einige Sekunden.
Dein Schlüsselbegriff muss nicht eindeutig sein, es gibt viele Familien, in denen Vater und Sohn den gleichen Vornamen haben und im gleichen Ort wohnen. Wenn Sie nun noch im gleichen Programm landen
da eine CDX die Texte komprimiert ablegt ist sie auf jeden Fall deutlich kleiner. Auch ist es - meiner Meinung nach - nicht richtig, dass immer die ganze Indexdatei geladen wird, solange nicht alle Datensätze der DBF gelesen werden. Xbase und Clipper ab 5.0 nutzen keine sequenziellen Indexdateien, die nur kleiner sind, sondern nutzen eine Art von Baumstruktur. Egal wie groß meine Indexe bisher waren (je etwa 20 MB bei 200 MB) und egal wie langsam das Netz war, DBSEEK() war immer sehr schnell.
Bei langsamen Leitungen (64KB) dauerte allerdings das Öffnen der DBF mit 3 bis 4 NTX Dateien einige Sekunden.
Dein Schlüsselbegriff muss nicht eindeutig sein, es gibt viele Familien, in denen Vater und Sohn den gleichen Vornamen haben und im gleichen Ort wohnen. Wenn Sie nun noch im gleichen Programm landen
Gruß
Hubert
Hubert
Möglichkeit der Datenverdichtung ...
Hallo Hubert,
die Möglichkeit der Verdichtung der Daten sowie der Erhöhung der Zugriffsgeschwindigkeit über eine Baumstruktur sinkt (nicht nur) mit der anteiligen Einmaligkeit der Information, spätestens bei der Rentenversicherungsnummer dürfte da Schluss sein (außerdem gibt es die Verwaltung der Baumstruktur auch nicht ganz umsonst). Eine Personalstammdatendatenbank benötigt dann auch noch weitere Schlüssel, mindestens noch die Personalnummer (über die man dann zurückschreibt). Ein Lesezugriff mit nur einer geöffneten sinnvoll gestalteten NTX - Indexdatei dürfte da schneller sein.
Um noch mal auf die Rentenversicherungsnummer zurückzukommen, innerhalb einer zu betrachtenden Menge (Unternehmen) ist die Wahrscheinlichkeit groß, das sich eine Rentenversicherungsnummer bereits bis zur vierten Stelle einmalig abbilden lässt. Hier würde der Index LEFT(RVSNR,4) völlig ausreichen, bekomme ich mehr als einen Datensatz zurück, dann wird anhand der direkt eingelesenen Daten noch einmal unterschieden (in diesem Beispiel würde der Primary Key die unternehmenseigene Personalnummer sein)
So, den Filter habe ich bei mir in der DLL eingebaut, nun muss ich noch den Rest durchprogrammieren und dann kommt noch das Schlimmtse, die Testphase.
Mit freundlichen Grüßen
Joachim Krause
die Möglichkeit der Verdichtung der Daten sowie der Erhöhung der Zugriffsgeschwindigkeit über eine Baumstruktur sinkt (nicht nur) mit der anteiligen Einmaligkeit der Information, spätestens bei der Rentenversicherungsnummer dürfte da Schluss sein (außerdem gibt es die Verwaltung der Baumstruktur auch nicht ganz umsonst). Eine Personalstammdatendatenbank benötigt dann auch noch weitere Schlüssel, mindestens noch die Personalnummer (über die man dann zurückschreibt). Ein Lesezugriff mit nur einer geöffneten sinnvoll gestalteten NTX - Indexdatei dürfte da schneller sein.
Um noch mal auf die Rentenversicherungsnummer zurückzukommen, innerhalb einer zu betrachtenden Menge (Unternehmen) ist die Wahrscheinlichkeit groß, das sich eine Rentenversicherungsnummer bereits bis zur vierten Stelle einmalig abbilden lässt. Hier würde der Index LEFT(RVSNR,4) völlig ausreichen, bekomme ich mehr als einen Datensatz zurück, dann wird anhand der direkt eingelesenen Daten noch einmal unterschieden (in diesem Beispiel würde der Primary Key die unternehmenseigene Personalnummer sein)
So, den Filter habe ich bei mir in der DLL eingebaut, nun muss ich noch den Rest durchprogrammieren und dann kommt noch das Schlimmtse, die Testphase.
Mit freundlichen Grüßen
Joachim Krause