Autor Beitrag
OlliWausD
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 212

Win 2000/XP
Delphi 5 Professional - Interbase/Firebird
BeitragVerfasst: Mi 19.01.05 13:05 
hi Leutz,

Ich hätte wiedermal eine kniffelige Frage:

In meiner Datenbank befinden sich ca 3000 "Char-Felder", von denen im Normalfall nur ca 2000 gefüllt werden, da der Kunde die Funktion, welche diese Felder benötigt nicht nutzt (benutzen darf, da er sie nicht gekauft hat) Jene benötigen somit immer den Speicherplatz des Char-Feldes (z.B.: 80 Byte) obwohl das Feld <null> ist.
Wenn ich mir dann die Vorgangspositionen dazu anschaue, wären das
ca 1.000.000 x 80 Byte = 76 MB um welche die DB kleiner werden würde.
(Komprimierung ausgeschlossen)

Mir ist jedoch auch bekannt, das VarChar einen größeren Zeitaufwand beim Speichern und Anzeigen von Datensätzen benötigt. Ist dieser Zeitaufwand minimal, oder zieht sich das bei Auswertungen "in die Länge"??

Würdet ihr mir dazu raten, und wenn ja, wie realisier ich das??

Ich denke mal, zur Realisierung benötige ich dann einen SQL-Code mit 'RDB$Field_Typ ...'
(zu MrSpock zwinker) :P

Hoffe mal, dass eine große Diskussion hier aufkommt :P

mfg

OlliW

_________________
Take it easy
MrSpock
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mi 19.01.05 13:42 
Hallo Olli,

die Zugriffszeiten habe ich nicht gemessen, aber bei den Datenmengen von denen du sprichst, dürfte diese Unterschied im Rauschen untergehen. Bei dieser Änderung brauchst du die Domain nicht zu ändern (obwohl das auch ginge), sondern du kannst das direct über SQL DDL machen:

ausblenden Quelltext
1:
alter table <tab1> alter <thevarfield> type varchar(10)					


oder, um die Änderung beim nächsten Mal zu vereinfachen:

ausblenden Quelltext
1:
CREATE DOMAIN nametyp AS VARCHAR(10)					


und dann:

ausblenden Quelltext
1:
alter table <tab1> alter <thevarfield> type nametyp					

_________________
Live long and prosper
MrSpock \\//
OlliWausD Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 212

Win 2000/XP
Delphi 5 Professional - Interbase/Firebird
BeitragVerfasst: Mi 19.01.05 14:12 
MrSpock hat folgendes geschrieben:
ausblenden Quelltext
1:
alter table <tab1> alter <thevarfield> type varchar(10)					

Das Würde bedeuten, ich müsste jedes Einzelne Feld anpacken, richtig?

Mein Updatescript ist sowieso schon über 5000 Zeilen ! Ohne Stored Procedures ! Die blanke Tipperei zum Ändern der Felder ist ganz schön Nerf-Tötend.

geht das nicht irgendwie mit RDB$Fied_Typ ..... damit ich das über die gesamt DB laufen lassen kann???

mfg

OlliW

ps: Ist der Geschwindigkeitsverlust wirklich so minimal??? Damals in der Schulzeit haben sie immer darauf getrimmt, varchar nur im Notfall zu benutzen, wegen der Geschwinigkeit!

_________________
Take it easy
OlliWausD Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 212

Win 2000/XP
Delphi 5 Professional - Interbase/Firebird
BeitragVerfasst: Mi 19.01.05 14:41 
haha !

hab die Lösung, wie es schneller funzt :)

- Erstellen 2 neuer Datenbanken
- Jeweils 1 Tabelle
- Jeweils 3 Felder (DB1 mit 3x Char und DB2 mit 3x Varchar)
- Databasecomparer sagt:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
UPDATE RDB$FIELDS SET RDB$FIELD_LENGTH=50,RDB$CHARACTER_LENGTH=50,
 RDB$FIELD_TYPE=37
  WHERE RDB$FIELD_NAME=(SELECT RDB$FIELD_SOURCE FROM RDB$RELATION_FIELDS
  WHERE RDB$FIELD_NAME='A' AND RDB$RELATION_NAME='NEW_TABLE');

UPDATE RDB$FIELDS SET RDB$FIELD_LENGTH=60,RDB$CHARACTER_LENGTH=60,
 RDB$FIELD_TYPE=37
  WHERE RDB$FIELD_NAME=(SELECT RDB$FIELD_SOURCE FROM RDB$RELATION_FIELDS
  WHERE RDB$FIELD_NAME='B' AND RDB$RELATION_NAME='NEW_TABLE');

UPDATE RDB$FIELDS SET RDB$FIELD_LENGTH=70,RDB$CHARACTER_LENGTH=70,
 RDB$FIELD_TYPE=37
  WHERE RDB$FIELD_NAME=(SELECT RDB$FIELD_SOURCE FROM RDB$RELATION_FIELDS
  WHERE RDB$FIELD_NAME='C' AND RDB$RELATION_NAME='NEW_TABLE');


Daraus macht man kurzer Hand:

ausblenden Quelltext
1:
UPDATE RDB$FIELDS SET RDB$FIELD_TYPE=37 where RDB$FIELD_TYPE=14					


und schon funzt alles :)

Ich stopp mal die Zeit nachdem ich unsere Demodatenbank durch die Mangel genommen habe, hehe

mfg

OlliW

EDIT:
zefix, Zu früh gefreut :x funktioniert doch nicht alles:

Fehlermeldung: Ungültiger Felddeskriptor

sagt das jemanden was?? Im Prinzip müsste sich doch nichts geändert haben, außer die Variable Länge des DB-Feldes!

_________________
Take it easy
MrSpock
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mi 19.01.05 14:58 
Hallo Olli,

wenn sich die Sortierreihenfolge und die Länge nicht ändern, könntest du ALLE Char in "gleichgroße" VARCHAR Felder umwandeln mit:

ausblenden Delphi-Quelltext
1:
update rdb$fields set rdb$field_type = 37 where rdb$field_type = 14					


Mach aber zur Sicherheit vorher eine Datensicherung! (Wie immer beim Manipulieren von Systemtabellen)

[edit]ooops, da warst du ja schneller als ich[/edit]

_________________
Live long and prosper
MrSpock \\//
OlliWausD Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 212

Win 2000/XP
Delphi 5 Professional - Interbase/Firebird
BeitragVerfasst: Mi 19.01.05 15:03 
hehe, ätsch :)

hast noch nen Tipp für mich???

_________________
Take it easy
MrSpock
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mi 19.01.05 16:06 
Hallo Olli,

wann kommt denn der Fehler mit dem Felddescriptor? Kannst du die Tabelle identifizieren, die den Fehler erzeugt? Dann wäre es interessant die genaue Felddefinition vor der "Umwandlung" anzuschauen. Außer dem Typ sind eigentlich nur noch der Zeichensatz, die Sortierung und die Feldlänge bei CHAR / VARCHAR wichtig. Das sind demnach Kandidaten für die Fehlerursache.

_________________
Live long and prosper
MrSpock \\//
OlliWausD Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 212

Win 2000/XP
Delphi 5 Professional - Interbase/Firebird
BeitragVerfasst: Mi 19.01.05 16:24 
Fehler Localisiert:

Im Programm wird eine TTable mit 3 Feldern geöffnet. (nr,bez,name)
- Nr = Integer;
- Bez = String;
- name= string;

Zeichensatz und Sortierreihenfolge sind nach dem Update identisch! Hat sich nichts geändert!


Beim Öffnen der Datenmenge (TableX.open) bringt er anschließend den Fehler.

tja, eigentlich dürfe das nichts ausmachen! Es sind weder Berechnungen noch Events im Table. Parameter zum Öffnen gibt es auch keine ! Nr ist Primärschlüssel!

Mehr gibts nicht.

hm... hängt es vielleicht an den Eigenschaften im Objektinspector???
Für Feld Bez und Name ist die DisplayWith 80, ebenso die Size.
Kann das hiermit zusammenhängen????

Will im Programm eigenltich nichts ändern. "Never Chance a running System!" Wie es so schön heisst.

_________________
Take it easy
MrSpock
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mi 19.01.05 16:44 
Hallo Olli,

ja, das könnte mit dem OI zusammenhängen. Besser gesagt mit den persistenten Feldern im DataSet Objekt. Es wäre sinnvoll an den Stellen, die Probleme machen, das Feld über den Feldeditor zu löschen und wieder einzufügen. Achte aber darauf, ob du dem Feld schon Code oder Darstellungsinformationen zugewiesen hast.

_________________
Live long and prosper
MrSpock \\//
OlliWausD Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 212

Win 2000/XP
Delphi 5 Professional - Interbase/Firebird
BeitragVerfasst: Mi 19.01.05 17:34 
jo,

ich verfolge die Sache mal weiter. Aber jetzt is erst mal Feierabend für heut :P

morgen folgt weiteres

mfg

OlliW

_________________
Take it easy