Binäre Daten von max 30 Bytes einfügen

Allgemeines zu PostgreSQL.

Binäre Daten von max 30 Bytes einfügen

Beitragvon hronny » So 13. Sep 2009, 14:24

Hallo alle miteinander!

Ich habe schon einiges mit postgresql an Daten gespeichert, aber mit binären Daten musste ich mich bisher nicht auseinandersetzen. Jetzt muss ich aber binäre Daten speichern die pro Datensatz maximal 30 Byte lang sind. Es muss kein Index drauf oder ähnliches. Was nimmt man als Datentyp dafür und wie muss ich das mit ANSI C in die Tabelle einfügen?

Gruß Ronny
hronny
Neuer Benutzer
 
Beiträge: 7
Registriert: So 13. Sep 2009, 14:07

Beitragvon ads » So 13. Sep 2009, 14:34

Du nimmst entweder ByteA als Datentyp und schreibst das direkt in die Tabelle oder du encodest das irgendwie (z. B. base64) und speicherst das in einem Feld vom Typ TEXT.

Ach ja, unter Umständen hilft dir noch ein:
[code]ALTER TABLE ... ALTER COLUMN ... SET STORAGE EXTERNAL;[/quote]
Das verhindert, dass die Daten von PG noch mal komprimiert werden.

Für den Zugriff aus C heraus gibt es PQescapeByteaConn. In ISBN 978-3-937514-69-7 ist die Anwendung ab Seite 284 beschrieben.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support
ads
Erfahrener Benutzer
 
Beiträge: 4147
Registriert: Mi 8. Feb 2006, 11:58
Wohnort: MD

Beitragvon hronny » So 13. Sep 2009, 19:29

Also nachdem ich weis nach was ich suchen muss hab ich derzeit folgende Lösung(?) gefunden: Testtabelle anlegen:
Code: Alles auswählen
CREATE TABLE testtbl (name text, daten bytea);
Daten einfügen:
Code: Alles auswählen
uchar buf[255];
unsigned char *to;
int len;

// .......
// Verarbeitung der Daten und ermitteln der Länge usw.
// .......
// Hiermit einfügen

to = PQescapeByteaConn(con, buf, len, &to_len);
sprintf(sqlquery, "INSERT INTO testtbl (name, daten) VALUES ('test', E'%s');", to);
hronny
Neuer Benutzer
 
Beiträge: 7
Registriert: So 13. Sep 2009, 14:07

Beitragvon ads » So 13. Sep 2009, 19:49

Wieso 255 Zeichen für "buf"?
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support
ads
Erfahrener Benutzer
 
Beiträge: 4147
Registriert: Mi 8. Feb 2006, 11:58
Wohnort: MD

Beitragvon hronny » So 13. Sep 2009, 20:19

Dachte ich reserviere schon genug vor, weil die Querys evtl so lang sein könnten. Was könnte evtl besser sein? In der späteren Anwendung werden bis zu 8 INSERT Befehle pro Sekunde zur Datenbank. Deshalb war ich der Meinung ohne malloc/free arbeiten zu können.

Ich freue mich natürlich auch über Verbesserungen. Mit C hab ich es nicht so sehr (arbeite sonst mit Delphi und PHP). Aber in diesem Fall geht es leider nicht anders.

Gruß Ronny
hronny
Neuer Benutzer
 
Beiträge: 7
Registriert: So 13. Sep 2009, 14:07

Beitragvon ads » So 13. Sep 2009, 20:26

Nun, "buf" ist in deinem Fall der Speicherplatz für die Daten, die du in die Datenbank schreiben möchtest. Laut deiner Aussage sind das maximal 30 Bytes. Warum reservierst du dann 255 Bytes?

Derartige Programme packe ich eher in die Ecke: ich weiß noch nicht, was letztendlich draus wird, also reserviere ich mal etwas mehr. Später vergesse ich das dann und handle mir einen Segfault samt Absturz und möglicher Code Injection ein.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support
ads
Erfahrener Benutzer
 
Beiträge: 4147
Registriert: Mi 8. Feb 2006, 11:58
Wohnort: MD

Beitragvon hronny » So 13. Sep 2009, 22:08

Ja richtig. Weil die 30 Byte ja "escaped" werden somit im ungünstigsten Fall 150 Bytes belegen. Wenn mein INSERT noch ein wenig komplexer wird, ist das nicht zu übertrieben. Lieber ein paar Bytes zu viel reserviert, als das es hinterher nicht "reinpasst" ;-)
hronny
Neuer Benutzer
 
Beiträge: 7
Registriert: So 13. Sep 2009, 14:07

Beitragvon ads » So 13. Sep 2009, 22:14

Nein, die 30 Bytes in "buf" bleiben 30 Bytes.

Es wäre fahrlässig, den übergebeben Speicherbereich einfach zu überschreiben, weil die Funktion gar nicht weiß, wie groß der Bereich reserviert wurde.

Nein, für das Ergebnis wird neuer Speicher reserviert, den du später wieder freigeben musst. Den Zeiger darauf bekommst du als Rückgabewert. Steht auch so alles in der Dokumentation.

Selbst wenn jedes einzelne Zeichen escaped wird und selbst wenn der Source-Bereich überschrieben werden würde, kommst du auf maximal 120 Zeichen Länge.


Vielleicht wäre es praktisch, wenn du dich vorab mit C beschäftigen würdest. Das ist eine Sprache, in der man sich schnell und gründlich in den Fuß schießen kann. Abgesehen von Assembler und einigen esoterischen Sprachen nimmt keine andere Sprache Programmierfehler so übel wie C.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support
ads
Erfahrener Benutzer
 
Beiträge: 4147
Registriert: Mi 8. Feb 2006, 11:58
Wohnort: MD

Beitragvon symbiont » Mo 14. Sep 2009, 15:42

hronny hat geschrieben:30 Byte


Was für Informationen sollen denn in den 30 Byte gespeichert werden - wenn ich fragen darf?!
symbiont
Erfahrener Benutzer
 
Beiträge: 1328
Registriert: Mo 17. Mär 2008, 12:45
Wohnort: NULL

Beitragvon hronny » Mo 14. Sep 2009, 19:38

Okay das mit den 255 Bytes reserviert hab ich verstanden. :) Nur wo der Speicher von dem Zeiger reserviert und freigegeben wird, ist mir derzeit völlig unklar. In der Beschreibung steht ja
PQescapeBytea ergibt eine Version der Binärdaten in from, in der alle Sonderzeichen durch Fluchtfolgen ersetzt wurden, sodass sie vom Zeichenkettenparser und von der bytea-Eingabefunktion ordnungsgemäß verarbeitet werden können. Der Ausgabepuffer wird mit malloc() angelegt. Ein abschließendes Null-Byte wird angehängt.
Würde ja bedeuten, dass ich nach meinem sprintf Befehl den Speicher direkt (selbst) freigeben muss, da sonst beim nächsten Aufruf neuer Speicher reserviert wird.
Ja ich weis das ist zwar der Befehl PQescapeBytea, aber er ist fast genauso wie PQescapeByteaConn, steht nur leider nicht in meinem Postgresql Handbuch drin.

Was für Informationen sollen denn in den 30 Byte gespeichert werden - wenn ich fragen darf?!
In den maximal 30 Bytes (meistens 9-12) werden die einzelnen Bustelegramme erfasst. Da hat fast jedes einzelne Bit eine Bedeutung zuzüglich Prüfsummen etc. Bisher hatte ich die Daten komplett in eine Struktur zerlegt in die Datenbank geschrieben. Dann hab ich festgestellt, dass das übertragen von 1 Mio Daten nach extern (selbst über DSL) viel zu lange dauert. Wenn ich die Daten binär übermittle und dann lokal wieder zerlege, könnte das deutlich schneller sein, als "reine ASCII" Zeichen zu übertragen.

Wichtig sind in der Datenbank eigentlich nur 4 Werte zum Eingrenzen oder Sortieren (Datum, Sender, Befehltyp, Datenwert). Die restlichen Infos sind nicht unwichtig, müssen aber nicht als einzelne Felder in die Datenbank. Somit finde ich es einfacher nur wenig Felder zu nutzen und bei Bedarf die eigentlichen Daten aus dem binären Feld herauszuholen.
hronny
Neuer Benutzer
 
Beiträge: 7
Registriert: So 13. Sep 2009, 14:07

Nächste

Zurück zu Allgemeines

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste