Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Record (mit Array) -> Datenbank / IBExpert (https://www.delphipraxis.net/177243-record-mit-array-datenbank-ibexpert.html)

Notxor 27. Okt 2013 21:10

Datenbank: Firebird • Version: 2.5 • Zugriff über: ZEOS

Record (mit Array) -> Datenbank / IBExpert
 
Hallo Leute,
ich bräuchte mal wieder etwas Hilfe.

Zu meinem Problem:
zZ. wird jeder Datensatz in einem Record gespeichert und diese in einer TList<> verwaltet, dann das ganze über TFileStream gespeichert. Der Zugang funktioniert, allerdings scheint es mir mittlerweile praktikabler, alles in einer Datenbank zu speichern.

Dazu habe ich mich für Firebird/Zeos entschieden und die DB mit IBExpert erstellt.
Mit den Standarddatentypen gibt es keine Probleme, allerdings kommen in dem Record viele
Delphi-Quellcode:
A: array[0..1] of Integer
vor, mit denen ich so meine Schwierigkeiten habe.

Über IBExpert konnte ich Feld-Arrays deklarieren, aber:
1) Wie weise ich diesem dann Daten zu? (mit IBExpert oder Delphi/Zeos)
Bzw. wie lese ich das Array dann aus?

Falls ich bei (1) nicht weiterkomme:
2) Ich lese jetzt immer wieder, dass Arrays in Datenbanken eigentlich nichts verloren haben, nur wie sollte ich das Record dann in der DB realisieren?
Mein (naiver) Zugang wäre 2 Spalten A_0, A_1 oder ähnlich zu erstellen, allerdings gibt es auch mehrdimensionale Arrays[0..1,0..4,0..3], bei denen dies doch etwas umständlich wäre ...

Ich denke das waren erst mal die wichtigeren Fragen, bin für jede Hilfe dankbar :) (ist mein erster Versuch mit Datenbanken)

EgonHugeist 27. Okt 2013 22:37

AW: Record (mit Array) -> Datenbank / IBExpert
 
Hi,

ich wollte das mal bei Zeos reinklimpern, genauso wie NestedTables für Oracle. Da aber leider FPC nachwievor NICHT mit Objekten, Intefaces, Arrays etc. klar kommt, habe ich das einfach unterlassen. Vielleicht mach ich's mal mit ein paar Delphi defines.

Jedoch kannst du die Array felder genauso, wie in Pascal EinArray[Index] splitten und somit die einzelnen Werte laden. Hab's schon getestet und funzt..

Hansa 27. Okt 2013 22:41

AW: Record (mit Array) -> Datenbank / IBExpert
 
Geh hin und lagere die bisherigen Array-Daten in separate Tabelle aus. Also wird eben
Delphi-Quellcode:
array [1..5] of integer;
in der Tabelle zu :
Code:
CREATE TABLE ARRAYTABLE (
    ID              INTEGER NOT NULL,
    ID_STAMMTABELLE INTEGER NOT NULL,
    ARRAYINDEX      SMALLINT NOT NULL,
    ARRAYWERT       DECIMAL(10,2) DEFAULT 0
);
Das hat sogar den Vorteil, dass nicht benötigte / 0 - Werte gar nicht erst in der DB drin sind.

Medium 28. Okt 2013 02:14

AW: Record (mit Array) -> Datenbank / IBExpert
 
Arrays innerhalb von Records schreien geradezu nach einer bzw. mehreren zusätzlichen Tabellen. Keine auch nur ansatzweise gut designte DB speichert in einem einzigen Feld mehrere Werte. Das ist schon fast eines der größten No-Gos, und selbst wenn ein DBMS so etwas unterstützen würde, wäre es im Handling (und sehr wahrscheinlich auch in Sachen Performance) ein kleiner Albtraum.

Furtbichler 28. Okt 2013 07:29

AW: Record (mit Array) -> Datenbank / IBExpert
 
Zitat:

Zitat von Medium (Beitrag 1233355)
Arrays innerhalb von Records schreien geradezu nach einer bzw. mehreren zusätzlichen Tabellen. Keine auch nur ansatzweise gut designte DB speichert in einem einzigen Feld mehrere Werte. Das ist schon fast eines der größten No-Gos, und selbst wenn ein DBMS so etwas unterstützen würde, wäre es im Handling (und sehr wahrscheinlich auch in Sachen Performance) ein kleiner Albtraum.

Das darf man so nicht unkommentiert stehenlassen, denn so allgemein gesprochen ist es schlichtweg falsch. Arrays in einer Spalte unterzubringen ist von der Performance her das Optimale, und vom Handling her auch. Es kommt natürlich immer drauf an ;-)

Wenn ich z.B. ein Array von Messwerten habe, die nur in Gänze innerhalb der DB eine Rolle spielen, dann kann und soll ich da sehr wohl in einem einzigen (z.B. BLOB) Feld abspeichern, so wie z.B. Bilder. Dort spielt das einzelne Pixel innerhalb der DB auch keine Rolle.

Habe ich jedoch z.B. ein Array of Namen, dann sollte ich den Aliasnamen selbst natürlich in einer separaten Tabelle ablegen.

Man muss den Begriff Wort 'Datum' (als Einzahl von Daten) im Kontext der Datenbank einfach genau definieren. Im Beispiel ist die 'Messreihe' ein einzelnes Datum (wenn man nie nach einzelnen Messergebnissen der Messreihe sucht). Ebenso das Bild (weil man nie nach 'Roter Pixel links oben' sucht).

Wenn ich jedoch nach alternativen Namen suchen möchte, dann breche ich mir, wie Medium das schon formuliert hat, mächtig einen Ab, wenn ich dieses Array nicht aufdrösele.

Notxor 31. Okt 2013 13:29

AW: Record (mit Array) -> Datenbank / IBExpert
 
So, tut mir leid dass ich mich erst jetzt wieder melde. Leider ist mir etwas dazwischen gekommen, wodurch ich ws erst nächste Woche an dem Programm weiterarbeiten kann.
Trotzdem schon mal Danke für die Antworten.

Bzw. schon mal eine Frage zu dem Bsp von Hansa:
Zitat:

Zitat von Hansa (Beitrag 1233349)
Code:
CREATE TABLE ARRAYTABLE (
    ID              INTEGER NOT NULL,
    ID_STAMMTABELLE INTEGER NOT NULL,
    ARRAYINDEX      SMALLINT NOT NULL,
    ARRAYWERT       DECIMAL(10,2) DEFAULT 0
);

Korrigiert mich, falls ich irgendwo daneben liege:

1) ID_STAMMTABELLE ist die "Referenz" zu den Hauptdaten, also wenn ich an die Array-Daten kommen will, nehme ich mir diese (eindeutige) ID_ST aus der Haupttabelle und suche im ArrayTable in der Spalte ID_STAMMTABLE danach und hole mir von dieser die Daten die ich will.

2a) Ist mit ID dann eine "zufällige", eindeutige Zahl gemeint (die nur von der DB benötigt wird wegen der Eindeutigkeit eines Datensatzes),
ODER
2b) soll hier sozusagen der Array-Name ("A", "B") hinein (und demnach alle Arrays (A[0..1], B[0..1], ... in diese eine Tabelle -> siehe unten).

3) Wird die DB durch das mitschleppen der Array-Indizes nicht unnötig groß? Wenn ich überlege: 100.000 Datensätze mit etwa 20 [0..1] Arrays und ein paar [0..1, 0..4, 0..4] Arrays, da kommen einige Indizes zusammen.

Main-Table:
ID_ST | NAME | DATUM | ...
1 | "Sp1"| 1.1.11| ...
17 | "Sp7"| 0.0.00| ...

Array-Table:
ID | ID_STAMMTABELLE | INDEX | WERT
"A" | 1 | 0 | 3
"A" | 1 | 1 | 5
"B" | 1 | 0 | 11
"B" | 1 | 1 | 19
"A" | 17 | 0 | 0
"A" | 17 | 1 | 2

Hansa 31. Okt 2013 14:22

AW: Record (mit Array) -> Datenbank / IBExpert
 
Zitat:

Zitat von Notxor (Beitrag 1233972)

Bzw. schon mal eine Frage zu dem Bsp von Hansa:
Zitat:

Zitat von Hansa (Beitrag 1233349)
Code:
CREATE TABLE ARRAYTABLE (
    ID              INTEGER NOT NULL,
    ID_STAMMTABELLE INTEGER NOT NULL,
    ARRAYINDEX      SMALLINT NOT NULL,
    ARRAYWERT       DECIMAL(10,2) DEFAULT 0
);

Korrigiert mich, falls ich irgendwo daneben liege:

1) ID_STAMMTABELLE ist die "Referenz" zu den Hauptdaten, also wenn ich an die Array-Daten kommen will, nehme ich mir diese (eindeutige) ID_ST aus der Haupttabelle und suche im ArrayTable in der Spalte ID_STAMMTABLE danach und hole mir von dieser die Daten die ich will.

2a) Ist mit ID dann eine "zufällige", eindeutige Zahl gemeint (die nur von der DB benötigt wird wegen der Eindeutigkeit eines Datensatzes),
ODER
2b) soll hier sozusagen der Array-Name ("A", "B") hinein (und demnach alle Arrays (A[0..1], B[0..1], ... in diese eine Tabelle -> siehe unten).

3) Wird die DB durch das mitschleppen der Array-Indizes nicht unnötig groß? Wenn ich überlege: 100.000 Datensätze mit etwa 20 [0..1] Arrays und ein paar [0..1, 0..4, 0..4] Arrays, da kommen einige Indizes zusammen.

Also : 1. ja, ID_STAMMTABELLE ist die Referenz. 2. Die ID ist die normalerweise von einem Trigger erzeugte ID der einzelnen Datensätze in der Tabelle.

Ich nehme Beispiel Artikel. Art.Nr. ist 100 und der hat die ID 111 Angenommen man will maximal 10 Array-Werte haben, braucht für den Artikel aber nur 3 Array-Werte <> 0. Die Array-Tabelle würde dann so aussehen : ID aus Generator von Trigger. ID_STAMMTABELLE wäre 111. Belegt werden Indizes 1,3,5 mit den Werten 10,30,50. Das sind dann 3 Datensätze. Mit Delphi Array wären es quasi 10. Jaja, die ID wird eben auch in der DB noch mitgeschleppt. 8-)

ID ist dann der Primary Key. ID_STAMMTABELLE ein Foreigne Key, der auf die Stammtabelle zeigt und zwar im Bsp. den Wert 111 hat. Dann am besten noch ein Unique setzen, zusammengesetzt aus ID_STAMMTABELLE und ARRAYINDEX, um das Ding eindeutig zu halten. Und, falls gewünscht noch ein ON DELETE CASCADE, damit alle Arraydaten mitgelöscht werden, wenn ein Datensatz in der Stammtabelle gelöscht wird. Sonst bleiben in der DB Leichen zurück beim löschen. War das jetzt alles ? :gruebel:

Zugriff wäre dann z.B. so :

Code:
SELECT ARRAYWERT FROM ARRAYTABLE WHERE ARRAYINDEX = 3 AND ID_STAMMTABELLE = 111
Das würde dann 30 liefern.

Notxor 31. Okt 2013 16:18

AW: Record (mit Array) -> Datenbank / IBExpert
 
Ok, denke dass ich dann schon auf einem guten Weg zum besseren Verständnis bin.
Allerdings gibt es in meinem Fall (so gut wie) keine Null-Einträge.
Werde es wohl einfach ausprobieren müssen, wie groß der Overhead dann wirklich wird.

Ob das alles war wird sich im Verlauf der nächsten Woche herausstellen, wenn ich Zeit habe das Ganze auch umzusetzen :coder2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz