Sollte ich VARCHAR-Spalten eine willkürliche Längenbeschränkung hinzufügen?


35

Laut PostgreSQLs docs , gibt es keinen Unterschied in der Leistung zwischen VARCHAR, VARCHAR(n)und TEXT.

Sollte ich einer Namens- oder Adressspalte eine beliebige Längenbeschränkung hinzufügen ?

Edit: Kein Betrug von:

Ich weiß, dass der CHARTyp ein Relikt der Vergangenheit ist, und ich interessiere mich nicht nur für Performance, sondern auch für andere Vor- und Nachteile, wie Erwin es in seiner erstaunlichen Antwort formuliert hat.

Antworten:


45

Die Antwort lautet nein .
Fügen Sie keinen Längenmodifikator hinzu, varcharwenn Sie dies vermeiden können. Meistens brauchen Sie sowieso keine Längenbeschränkung. Einfach textfür alle Charakterdaten verwenden. Nehmen Sie dies vor varchar(kein Längenmodifikator), wenn Sie mit RDBMS kompatibel bleiben müssen, für die es keine gibt text.

Die Leistung ist fast gleich - textist in seltenen Situationen etwas schneller , und Sie speichern die Zyklen für die Überprüfung der Länge.

Wenn Sie tatsächlich benötigen eine maximale Länge zu erzwingen, noch verwenden textein und fügen Sie Check - Bedingung dafür:

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);

Sie können eine solche Einschränkung jederzeit ändern oder löschen, ohne sich mit der Tabellendefinition und allen abhängigen Objekten (Ansichten, Funktionen, Fremdschlüssel, ...) herumschlagen zu müssen.

Mit Längenmodifikatoren stoßen Sie einfach auf Probleme wie dieses oder jenes oder jenes ...

PostgreSQL 9.1 führte eine neue Funktion ein, um die Schmerzen etwas zu lindern. Ich zitiere die Release Notes hier :

Lassen Sie ALTER TABLE ... SET DATA TYPETabelle Neufassungen in geeigneten Fällen vermeiden (Noah Misch, Robert Haas)

Wenn Sie beispielsweise eine varcharSpalte in Text konvertieren, muss die Tabelle nicht mehr neu geschrieben werden. Das Erhöhen der Längenbeschränkung für eine varcharSpalte erfordert jedoch weiterhin ein Umschreiben der Tabelle.


Ich denke, diese Antwort wäre viel besser, wenn es einfach "Nein, füge niemals einer echten Datenbank willkürliche Grenzen hinzu" wäre. Ich bin der Meinung, dass ein Großteil dieser Antwort Korrekturen und weitere Informationen erfordert, dass sie jedoch völlig vom Thema abweicht und von Ihrer Schlussfolgerung ablenkt, der ich vollkommen zustimme.
Evan Carroll

Ja, alle basieren auf Postgres-Versionen vor 9.1 - 6 Jahren. Ein bisschen staubig, aber die grundlegenden Ratschläge sind immer noch gut.
Erwin Brandstetter

Ist es eine gute oder schlechte Idee, für jede Textspalte eine Check-Einschränkung hinzuzufügen, um sicherzustellen, dass ein Fehler im Client nicht den gesamten Speicherplatz der Datenbank beansprucht, indem ein sehr großer Text eingefügt wird?
Code

@ Code: Es ist eine praktikable Option. Wenn Sie viele Spalten mit derselben Einschränkung haben, ziehen Sie Domänen in Betracht . Oder der varchar(n)Einfachheit halber - wenn die Nachteile Sie normalerweise nicht betreffen. (Das Limit ist in Ihrem Fall nicht willkürlich , wenn Sie eine tatsächliche maximale Länge erzwingen möchten.)
Erwin Brandstetter,

12

Wenn Sie die Längenbeschränkung als eine Art Prüfbedingung sehen, um sicherzustellen, dass Sie die Daten validieren, fügen Sie eine hinzu. Möglicherweise möchten Sie keine Längendefinition, sondern eine echte Prüfbedingung verwenden, um die Änderung des Grenzwerts zu beschleunigen.

Um eine Längenbeschränkung zu ändern (zu erhöhen), müssen Sie eine ausführen, ALTER TABLEderen Abschluss (aufgrund eines möglichen erneuten Schreibens der Tabelle) möglicherweise lange dauert, während der eine exklusive Tabellensperre erforderlich ist.

Das Ändern (dh Löschen und Neuerstellen) einer Prüfbedingung ist ein sehr kurzer Vorgang und erfordert nur das Lesen der Tabellendaten. Es werden keine Zeilen geändert. Das geht also viel schneller (was wiederum bedeutet, dass die exklusive Tischsperre viel kürzer gehalten wird).

Während des Betriebs gibt es keinen Unterschied zwischen einer text, einer varcharoder einer varchar(5000)Säule.


Warum kann diese Längenprüfung aus reiner Neugier bei einer Clientanwendung während der Datenerfassung nicht durchgeführt werden?
PirateApp

4
@PirateApp: weil es sehr oft mehr als eine Anwendung oder eine externe Datenquelle gibt (denken Sie an nächtliche Batch-Importe). Und fast immer leben die Datenbank (und die Daten) länger als eine Anwendung.
a_horse_with_no_name

2

Die Frage ist speziell, ob VARCHAR-Spalten eine willkürliche Längenbeschränkung hinzugefügt werden soll .

Darauf lautet die Antwort einfach "nein". Nichts kann es rechtfertigen, ein beliebiges Limit hinzuzufügen, wie Sie es in minderwertigen Datenbanken tun würden, varchar(max)die Konventionen wie diese unterstützen oder verwenden varchar(255). Wenn sich die Spezifikation jedoch mit einem Limit befasst, wird die Antwort meiner Meinung nach viel komplexer, insbesondere bei modernen Versionen von PostgreSQL. Und dafür würde ich mich zu JA neigen .

Meiner Meinung nach ist das Limit eine kluge Wahl, wenn die Spezifikation es erfordert. Besonders für vernünftigere Arbeitslasten. Wenn aus keinem anderen Grund, dann um Metadaten zu erhalten.

Aus meiner Antwort hier, Indexleistung für CHAR vs VARCHAR (Postgres) , wo ich den Wert von Metadaten anspreche.

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. Mir fällt jedoch nichts ein, das diesen Kriterien entspricht.


1

Es sieht so aus, als ob es einige Leistungsunterschiede geben könnte, wenn VARCHARregelmäßig sehr große Zeichenfolgen gespeichert werden, da "lange Zeichenfolgen vom System automatisch komprimiert werden" und "sehr lange Werte auch in Hintergrundtabellen gespeichert werden". Theoretisch würde dies bedeuten, dass ein hohes Anforderungsvolumen für ein sehr langes Zeichenfolgenfeld langsamer ist als für ein kurzes Zeichenfolgenfeld. Sie werden wahrscheinlich nie auf dieses Problem stoßen, da Namen und Adressen nicht sehr lang sein werden.

Abhängig davon, wie Sie diese Zeichenfolgen außerhalb Ihrer Datenbank verwenden, möchten Sie möglicherweise ein praktisches Limit hinzufügen, um einen Missbrauch des Systems zu verhindern. Wenn Sie beispielsweise den Namen und die Adresse in einem Formular irgendwo anzeigen, können Sie möglicherweise nicht den gesamten Textabschnitt im Feld "Name" anzeigen. Daher ist es sinnvoll, die Namensspalte auf 500 zu beschränken Zeichen.


1
AFAIK gibt es keinen Unterschied in TOASTing varchar und Textfeldern.
Dezso

VARCHARist rein syntaktischer Zucker für TEXTPostgres, es gibt keinen Unterschied in der Lagerung; Die Komprimierung im Vergleich zum Hintergrundtabellenspeicher, die Sie erwähnen, basiert auf der tatsächlichen Länge der Daten in der Spalte und nicht auf den Spaltenmetadaten. TEXT-Spalten werden intern als varlenaC-Struktur gespeichert (ein Array mit variabler Länge, wobei die ersten 4 Bytes die Länge beim Erstellen / Aktualisieren speichern). Diese Struktur wird basierend auf ihrer Länge optimiert.
Cowbert
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.