Soll ich die PostgreSQL-Bitfolge verwenden?

18

Ich habe in bit stringletzter Zeit etwas über den Datentyp gelernt und bin ziemlich neugierig auf:

  1. Am Ende dieser Dokumentseite befindet sich der Satz:

    ... plus 5 oder 8 Byte Overhead, abhängig von der Länge des Strings

  2. Wie werden Bitstrings in anderen Sprachen wie PHP, Java, C #, C ++ usw. über Treiber wie Npgsql, ODBC usw. behandelt?

Bei Frage 1 ist die Verwendung von smallint oder bigint wesentlich speichereffizienter und bietet möglicherweise einen Leistungsgewinn, da Ganzzahlen überall unterstützt werden. Die meisten Programmiersprachen verarbeiten problemlos Bitoperationen für Ganzzahlen. Wenn dies der Fall ist, wozu dient dann der Datentyp Bitfolge? Ist es nur für Fälle, die eine große Anzahl von Bitmasken benötigen? Bitfeldindizierung vielleicht? Ich bin eher neugierig, wie die Bitfeldindizierung in PostgreSQL durchgeführt wird.

Für # 2 bin ich verwirrt, mehr als neugierig. Was ist zum Beispiel, wenn ich Wochentag-Bitmasken in einem Bit (7) -Feld speichere, ein Bit für einen Tag, wobei das niedrigste Bit für Montag steht. Dann frage ich nach dem Wert in PHP und C ++. Was bekomme ich? In der Dokumentation steht, dass ich eine Bit-Zeichenfolge haben werde, aber eine Bit-Zeichenfolge kann ich nicht direkt verwenden - wie bei ganzen Zahlen. Sollte ich dann in diesem Fall das Bitfeld aufgeben?

Kann jemand erläutern, warum und wann ich etwas oder etwas variieren sollte?

Jackey Cheung
quelle
2
Erwins Antwort auf SO ist großartig (und wenn es Ihnen nichts ausmacht, sie über @Erwin zu kopieren, wäre es nützlich, sie hier zu haben), aber ich möchte meine eigene Vorsicht hinzufügen: In den meisten Fällen würden Sie nicht darüber nachdenken, Informationen zu speichern in Bit-Strings auf einem RDBMS - unter Verwendung separater Boolescher Spalten in der normalen Lösung, unabhängig von der 'Speichereffizienz'.
Jack Douglas
@JackDouglas: Es würde mir nichts ausmachen, meine Antwort zu kopieren. Ich frage mich jedoch: Ist es eine gute Idee, eine Antwort über mehrere SE-Standorte hinweg zu duplizieren?
Erwin Brandstetter,
@Erwin Ich verstehe nicht, warum nicht - es gibt eine gewisse Überlappung zwischen den Sites, und beide sollten allein stehen (zum Beispiel würden wir hier keine Frage als Duplikat schließen, wenn es eine gäbe) eine identische Frage zu SO). Unser Fokus liegt mehr auf 'Experten'-Themen, aber IMO passt Ihre Antwort in diese Kategorie, wie sie ist :)
Jack Douglas
@ JackDouglas: Na ja, macht Sinn. Und wie könnte ich überhaupt anderer Meinung sein, nachdem das Lob, in das Sie hineingeschlichen sind? ;)
Erwin Brandstetter

Antworten:

18

Wenn Sie nur ein paar Variablen haben, würde ich in Betracht ziehen, separate booleanSpalten zu führen.

  • Die Indizierung ist einfach. Insbesondere sind Indizes zu Ausdrücken einfach.
  • Bedingungen für Abfragen und Teilindizierungen sind einfach zu schreiben und zu lesen und aussagekräftig.
  • Eine Boolesche Spalte belegt 1 Byte. Für nur wenige Variablen nimmt dies den geringsten Platz ein.
  • Im Gegensatz zu den anderen Optionen erlauben boolesche Spalten NULLWerte für einzelne Bits, falls Sie diese benötigen sollten. Sie können immer Spalten definieren, NOT NULLwenn Sie dies nicht tun.

Speicher optimieren

Wenn Sie mehr als eine Hand voll Variablen haben , aber weniger als 33, eine integerSpalte können Sie am besten dienen. (Oder a bigintfür bis zu 64 Variablen.)

  • Belegt 4 Bytes auf der Festplatte.
  • Sehr schnelle Indizierung für exakte Übereinstimmungen ( =Operator).
  • Der Umgang mit einzelnen Werten kann langsamer / unbequemer sein als mit bit stringoder boolean.

Mit noch mehr Variablen, oder wenn Sie die Werte viel manipulieren möchten, oder wenn Sie nicht über große Tabellen und Speicherplatz / RAM verfügen, ist dies kein Problem, oder wenn Sie nicht sicher sind, was Sie auswählen sollen, würde ich bit(n)oder inbit varying(n) Betracht ziehen .

  • Besetzt mindestens 5 Bytes (oder 8 für sehr lange Zeichenfolgen) plus 1 Byte für jede Gruppe von 8 Bits (aufgerundet).
  • Sie können Bitstring-Funktionen und -Operatoren direkt verwenden.

Beispiele

Für nur 3 Informationsbits kommen einzelne booleanSpalten mit 3 Bytes aus, eine integerbenötigt 4 Bytes und eine bit string6 Bytes (5 + 1).

Für 32 Informationsbits integerbenötigt ein noch 4 Bytes, ein bit stringbelegt 9 Bytes für dasselbe (5 + 4) und booleanSpalten belegen 32 Bytes.

Weitere Lektüre

Erwin Brandstetter
quelle
Ja, ich stimme dir zu. Momentan verwende ich samllint, um die Bitmaske der Wochentage zu speichern. Es passte dem Fall, Speichereffizienz / Leistung breit. Wenn ich jedoch mehr Indizierung / Filterung für Bitmasken hätte, schlägt dies aufgrund der geringen Leistung fehl.
Jackey Cheung
3

Alle PostgreSQL-Typen sind für einige Dinge nützlich und für andere weniger nützlich. Im Allgemeinen müssen Sie sich erst um die Funktionalität und später um die Leistung kümmern. PostgreSQL verfügt über eine Vielzahl von Funktionen zur Bearbeitung verschiedener Datentypen, die keine Ausnahme bilden.

Ich würde erwarten, auf der Anwendungsebene, wenn Ihr DB-Treiber es durch eine Art Typkonvertierung behandelt, würden Sie eine Zeichenfolgendarstellung erhalten und müssen dies behandeln. Daher kann es in dieser Eigenschaft nützlich sein oder auch nicht.

Dies ist wahrscheinlich hilfreich, wenn Sie Datensätze basierend auf bitweisen Operationen auswählen möchten, z. B. bitweise oder bitweise und oder die Daten in SQL-Abfragen anderweitig bearbeiten möchten. Wenn Sie dies nicht tun, sind viele der esoterischeren Funktionen von PostgreSQL weniger hilfreich.

Beachten Sie auch, dass es für längere Zeichenfolgen von Binärinformationen eine große Objektschnittstelle gibt, mit der Sie Streaming usw. durchführen können, und eine Bytea-Schnittstelle, die eine kompaktere Darstellung von Zeichenfolgen ermöglicht.

tl; dr .: Wenn du es brauchst, wirst du es wissen. Andernfalls legen Sie es im Abschnitt "Für zukünftige Verwendung reserviert" ab.

Chris Travers
quelle