Denken Sie auch daran, dass es beim Indexvergleich oft einen großen Unterschied zwischen einem CHAR und einem VARCHAR gibt
Gilt das / gilt das noch für Postgres?
Ich habe Seiten auf Oracle gefunden, die behaupten, dass dies CHARmehr oder weniger ein Alias für VARCHARdie gleiche Indexleistung ist, aber auf Postgres habe ich nichts Bestimmtes gefunden.
CHARund VARCHARsind in Postgres (und Oracle) genau gleich implementiert. Bei Verwendung dieser Datentypen besteht kein Geschwindigkeitsunterschied.
Es gibt jedoch einen Unterschied, der sich auf die Leistung charauswirken kann : Eine Spalte wird immer auf die festgelegte Länge aufgefüllt. Wenn Sie also eine Spalte als char(100)und eine als definieren, varchar(100)aber jeweils nur 10 Zeichen speichern, verwendet die char(100)Spalte 100 Zeichen für jeden Wert (die 10 Zeichen, die Sie gespeichert haben, plus 90 Leerzeichen), während die varcharSpalte nur 10 Zeichen speichert.
Das Vergleichen von 100 Zeichen mit 100 Zeichen ist langsamer als das Vergleichen von 10 Zeichen mit 10 Zeichen - obwohl ich bezweifle, dass Sie diesen Unterschied in einer SQL-Abfrage tatsächlich messen können.
Wenn Sie beide mit der Länge von 10 Zeichen deklarieren und immer genau 10 Zeichen darin speichern , gibt es überhaupt keinen Unterschied (dies gilt für Oracle und Postgres).
Der einzige Unterschied besteht also in der Auffüllung des charDatentyps.
Denken Sie auch daran, dass es beim Indexvergleich oft einen großen Unterschied zwischen einem CHAR und einem VARCHAR gibt
Das obige Zitat ist nur dann zutreffend, wenn (und nur dann) die charSpalte zu breit definiert ist (dh Sie verschwenden Platz aufgrund von Auffüllung). Wenn die Länge der charSpalte immer vollständig ausgenutzt wird (also keine Auffüllung erfolgt), ist das obige Zitat falsch (zumindest für Postgres und Oracle).
Aus meiner Sicht ist der charDatentyp nicht wirklich wortgetreu. Verwenden Sie einfach varchar(oder textin Postgres) und vergessen Sie, dass es charexistiert.
Das Vergleichen von 100 Zeichen mit 100 Zeichen ist langsamer als das Vergleichen von 10 Zeichen mit 10 Zeichen - obwohl ich bezweifle, dass Sie diesen Unterschied in einer SQL-Abfrage tatsächlich messen können. - Abhängig davon, was die Abfrage zusätzlich zum Sortieren macht, kann der Unterschied sehr groß sein. Aus diesem Grund hat Postgres 9.5 eine neue Funktion für abgekürzte Schlüssel: pgeoghegan.blogspot.de/2015/01/…
chirlu
6
Ich stimme allem zu , was a_horse_with_no_name sagt, und ich stimme generell Erwins Kommentar zu:
Nein, char ist minderwertig (und veraltet). text und varchar verhalten sich (fast) gleich.
Metadaten
Mit einer kleinen Ausnahme benutze ich nur dann, char()wenn die Metadaten besagen sollen, dass diese X-Zeichen enthalten MÜSSEN . Obwohl ich weiß, dass sich char()nur beschwert, wenn die Eingabe den Grenzwert überschreitet, werde ich mich häufig vor Unterläufen in einer CHECKEinschränkung schützen . Beispielsweise,
CREATETABLE foo (
x char(10)CHECK( length(x)=10));INSERTINTO foo VALUES(repeat('x',9));
Ich mache das aus ein paar Gründen,
char(x)wird bei Schemaladern manchmal als Spalte mit fester Breite gefolgert. Dies kann einen Unterschied in einer Sprache bewirken, die für Zeichenfolgen mit fester Breite optimiert ist.
Es schafft eine Konvention, die Sinn macht und leicht durchgesetzt werden kann. Ich kann einen Schema-Loader in einer Sprache schreiben, um aus dieser Konvention Code zu generieren.
Brauchen Sie ein Beispiel, wo ich das tun darf,
Zwei-Buchstaben-Abkürzungen, da diese Liste jedoch aufgezählt werden kann, mache ich das normalerweise mit einem ENUM.
Beachten Sie, dass einige Leute mit der Inkongruenz von Fehlermeldungen auf beiden Seiten des Limits unzufrieden sind, aber es stört mich nicht
test=#INSERTINTO foo VALUES(repeat('x',9));
ERROR: new rowfor relation "foo" violates checkconstraint"foo_x_check"
DETAIL: Failing rowcontains(xxxxxxxxx ).
test=#INSERTINTO foo VALUES(repeat('x',11));
ERROR: value too long for type character(10)
Kontrast zu varchar
Darüber hinaus denke ich, dass der obige Vorschlag wirklich gut zu einer Konvention passt, die fast immer verwendet wirdtext . Sie fragen varchar(n)auch nach. Ich benutze das nie . Zumindest kann ich mich nicht an das letzte Mal erinnern, als ich es benutzt habe varchar(n).
Wenn eine Spezifikation ein statisches Breitenfeld hat , dass ich vertrauen, ich benutze char(n),
Ansonsten nutze ich textwas effektiv ist varchar(no limit)
Wenn ich eine Spezifikation mit aussagekräftigen Textschlüsseln variabler Länge und einer konstanten Maximallänge finden würde, würde ich diese ebenfalls verwenden varchar(n). Mir fällt jedoch nichts ein, was diesen Kriterien entspricht.
sales_reporting_db=#createtable x (y char(2));CREATETABLE
sales_reporting_db=#insertinto x values('Y');INSERT01
sales_reporting_db=#select'*'|| y ||'*'from x;?column?----------*Y*
Orakel
SQL>createtable x ( y char(2));Table created.
SQL>insertinto x values('Y');1row created.
SQL>select'*'|| y ||'*'from x;'*'|----*Y *
Ich stimme allem zu , was a_horse_with_no_name sagt, und ich stimme generell Erwins Kommentar zu:
Metadaten
Mit einer kleinen Ausnahme benutze ich nur dann,
char()
wenn die Metadaten besagen sollen, dass diese X-Zeichen enthalten MÜSSEN . Obwohl ich weiß, dass sichchar()
nur beschwert, wenn die Eingabe den Grenzwert überschreitet, werde ich mich häufig vor Unterläufen in einerCHECK
Einschränkung schützen . Beispielsweise,Ich mache das aus ein paar Gründen,
char(x)
wird bei Schemaladern manchmal als Spalte mit fester Breite gefolgert. Dies kann einen Unterschied in einer Sprache bewirken, die für Zeichenfolgen mit fester Breite optimiert ist.Brauchen Sie ein Beispiel, wo ich das tun darf,
ENUM
.Bei Fehlern
Beachten Sie, dass einige Leute mit der Inkongruenz von Fehlermeldungen auf beiden Seiten des Limits unzufrieden sind, aber es stört mich nicht
Kontrast zu
varchar
Darüber hinaus denke ich, dass der obige Vorschlag wirklich gut zu einer Konvention passt, die fast immer verwendet wird
text
. Sie fragenvarchar(n)
auch nach. Ich benutze das nie . Zumindest kann ich mich nicht an das letzte Mal erinnern, als ich es benutzt habevarchar(n)
.char(n)
,text
was effektiv istvarchar
(no limit)Wenn ich eine Spezifikation mit aussagekräftigen Textschlüsseln variabler Länge und einer konstanten Maximallänge finden würde, würde ich diese ebenfalls verwenden
varchar(n)
. Mir fällt jedoch nichts ein, was diesen Kriterien entspricht.Zusätzliche Bemerkungen
char
Hier ist nicht zu verwechseln,"char"
welche ein Ein-Byte-Typ ist und solide Leistung und platzsparende Vorteile hat.Verwandte Fragen und Antworten:
quelle
Postgresql
Orakel
Postgresql füllte nicht mit Leerzeichen auf.
quelle
SELECT pg_column_size(y) FROM x;
Ich fand das am nützlichsten und eine schnelle 3-zeilige Erklärung:
quelle