web-dev-qa-db-ger.com

Bewährte Methoden für die SQL-Varchar-Spaltenlänge

Jedes Mal, wenn eine neue SQL-Tabelle erstellt oder eine neue Spalte varchar zu einer vorhandenen Tabelle hinzugefügt wird, frage ich mich, was der beste Wert für length ist.

Nehmen wir an, Sie haben eine Spalte mit dem Namen name vom Typ varchar. Sie müssen also die Länge auswählen. Ich kann mir keinen Namen mit mehr als 20 Zeichen vorstellen, aber Sie werden es nie erfahren. Aber anstatt 20 zu verwenden, runde ich immer auf die nächste 2 ^ n-Zahl auf. In diesem Fall würde ich 32 als Länge wählen. Ich mache das, weil aus Sicht der Informatiker eine Zahl 2 ^ n für mich mehr even ist als andere Zahlen, und ich gehe nur davon aus, dass die Architektur darunter mit diesen Zahlen etwas besser umgehen kann als andere.

Auf der anderen Seite legt der MSSQL-Server zum Beispiel die Standardlänge auf 50 fest, wenn Sie eine varchar-Spalte erstellen. Das bringt mich zum Nachdenken. Warum 50? Ist es nur eine Zufallszahl oder basiert es auf der durchschnittlichen Spaltenlänge oder was?

Es könnte auch sein - oder wahrscheinlich auch -, dass verschiedene SQL Server-Implementierungen (wie MySQL, MSSQL, Postgres, ...) unterschiedliche Werte für die beste Spaltenlänge aufweisen.

264
esskar

Kein mir bekanntes DBMS verfügt über eine "Optimierung", durch die eine VARCHAR mit einer Länge von 2^n Eine bessere Leistung erzielt als eine mit einer Länge von max, die keine Potenz von 2 ist.

Ich denke, frühe SQL Server-Versionen haben tatsächlich ein VARCHAR mit einer Länge von 255 anders behandelt als eines mit einer höheren maximalen Länge. Ich weiß nicht, ob das noch der Fall ist.

Bei fast allen DBMS wird der tatsächlich erforderliche Speicher nur durch die Anzahl der eingegebenen Zeichen bestimmt, nicht durch die von Ihnen definierte Länge von max. Aus Sicht der Speicherung (und höchstwahrscheinlich auch der Leistung) spielt es also keine Rolle, ob Sie eine Spalte als VARCHAR(100) oder VARCHAR(500) deklarieren.

Sie sollten die für eine max -Spalte angegebene VARCHAR -Länge eher als eine Art Einschränkung (oder Geschäftsregel) als eine technische/physikalische Sache betrachten.

Für PostgreSQL ist es am besten, text ohne Längenbeschränkung und mit einem CHECK CONSTRAINT Zu verwenden, der die Anzahl der Zeichen auf die Anforderungen Ihres Unternehmens beschränkt.

Wenn sich diese Anforderung ändert, ist das Ändern der Prüfbedingung viel schneller als das Ändern der Tabelle (da die Tabelle nicht neu geschrieben werden muss).

Das Gleiche gilt für Oracle und andere - in Oracle wäre es jedoch VARCHAR(4000) anstelle von text.

Ich weiß nicht, ob es einen physischen Speicherunterschied zwischen VARCHAR(max) und z. VARCHAR(500) in SQL Server. Offensichtlich hat die Verwendung von varchar(max) im Vergleich zu varchar(8000) jedoch einen Einfluss auf die Leistung.

Siehe diesen Link (gepostet von Erwin Brandstetter als Kommentar)

Bearbeiten 22.09.2013

Zu bigowns Kommentar:

In Postgres-Versionen vor 9.2 (die nicht verfügbar waren, als ich die erste Antwort schrieb) wurde die Spaltendefinition geändert did die gesamte Tabelle neu geschrieben, siehe z. hier . Seit 9.2 ist dies nicht mehr der Fall und ein schneller Test bestätigte, dass die Erhöhung der Spaltengröße für eine Tabelle mit 1,2 Millionen Zeilen tatsächlich nur 0,5 Sekunden dauerte.

Dies scheint auch für Oracle zuzutreffen, wenn man bedenkt, wie lange es dauert, die varchar -Spalte einer großen Tabelle zu ändern. Aber ich konnte keinen Hinweis dafür finden.

Für MySQL im Handbuch steht " In den meisten Fällen erstellt ALTER TABLE Eine temporäre Kopie der Originaltabelle". Und meine eigenen Tests bestätigen Folgendes: Das Ausführen eines ALTER TABLE Für eine Tabelle mit 1,2 Millionen Zeilen (wie in meinem Test mit Postgres) zum Vergrößern einer Spalte dauerte 1,5 Minuten. In MySQL können Sie jedoch nicht die "Problemumgehung" verwenden, um eine Check-Einschränkung zu verwenden, um die Anzahl der Zeichen in einer Spalte zu begrenzen.

Für SQL Server konnte ich keine eindeutige Aussage dazu finden, aber die Ausführungszeit zur Vergrößerung einer varchar -Spalte (wieder die 1,2-Millionen-Zeilen-Tabelle von oben) zeigt an, dass es findet kein Umschreiben statt.

Bearbeiten 24.01.2017

Anscheinend habe ich mich (zumindest teilweise) in Bezug auf SQL Server geirrt. Siehe diese Antwort von Aaron Bertrand das zeigt, dass die deklarierte Länge einer nvarchar oder varchar Spalte einen großen Unterschied für die Leistung macht.

219

VARCHAR(255) und VARCHAR(2) nehmen genau den gleichen Speicherplatz auf der Festplatte ein! Der einzige Grund, dies einzuschränken, ist, wenn Sie einen bestimmten Bedarf haben, dass es kleiner ist. Ansonsten mache sie alle 255.

Insbesondere beim Sortieren nimmt eine größere Spalte mehr Platz ein. Wenn dies also die Leistung beeinträchtigt, müssen Sie sich darum kümmern und sie verkleinern. Wenn Sie jedoch immer nur eine Zeile aus dieser Tabelle auswählen, können Sie sie alle zu 255 machen, und es spielt keine Rolle.

Siehe: Was sind die optimalen Varchar-Größen für MySQL?

59
Ariel

Immer, wenn ich eine neue SQL-Tabelle einrichte, empfinde ich 2 ^ n als "gerade", aber um die Antworten hier zusammenzufassen: Es gibt keine signifikanten Auswirkungen auf den Speicherplatz, wenn ich einfach varchar (2 ^ n) definiere. oder sogar varchar (MAX).

Dennoch sollten Sie die möglichen Auswirkungen auf die Speicherung und Leistung beim Festlegen eines hohen varchar () - Grenzwerts berücksichtigen. Angenommen, Sie erstellen eine varchar (MAX) -Spalte für Produktbeschreibungen mit Volltextindizierung. Wenn 99% der Beschreibungen nur 500 Zeichen lang sind und Sie plötzlich jemanden finden, der diese Beschreibungen durch Wikipedia-Artikel ersetzt, werden Sie möglicherweise unerwartete erhebliche Speicher- und Leistungstreffer bemerken.

Noch etwas von Bill Karwin zu beachten :

Es gibt eine mögliche Auswirkung auf die Leistung: In MySQL speichern temporäre Tabellen und MEMORY-Tabellen eine VARCHAR-Spalte als Spalte mit fester Länge, die auf ihre maximale Länge aufgefüllt ist. Wenn Sie VARCHAR-Spalten entwerfen, die viel größer als die von Ihnen benötigte Größe sind, verbrauchen Sie mehr Speicher als erforderlich. Dies wirkt sich auf die Cache-Effizienz, die Sortiergeschwindigkeit usw. aus.

Überlegen Sie sich im Grunde nur vernünftige geschäftliche Einschränkungen und Fehler bei einer etwas größeren Größe. Wie @onedaywenn darauf hingewiesen, sind Familiennamen in Großbritannien in der Regel zwischen 1-35 Zeichen. Wenn Sie sich für varchar (64) entscheiden, werden Sie nichts wirklich verletzen ... es sei denn, Sie speichern der Familienname dieses Typen das soll bis zu 666 Zeichen lang sein. In diesem Fall ist varchar (1028) möglicherweise sinnvoller.

Und falls es hilfreich sein sollte, sehen die Variablen 2 ^ 5 bis 2 ^ 10 so aus, wenn sie gefüllt sind:

varchar(32)     Lorem ipsum dolor sit amet amet.

varchar(64)     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie

varchar(128)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas

varchar(256)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt

varchar(512)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie

varchar(1024)   Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie
                dapibus leo lobortis eleifend. Vivamus vitae diam turpis. Vivamu
                nec tristique magna, vel tincidunt diam. Maecenas elementum semi
                quam. In ut est porttitor, sagittis nulla id, fermentum turpist.
                Curabitur pretium nibh a imperdiet cursus. Sed at vulputate este
                proin fermentum pretium justo, ac malesuada eros et Pellentesque
                vulputate hendrerit molestie. Aenean imperdiet a enim at finibus
                fusce ut ullamcorper risus, a cursus massa. Nunc non dapibus vel
                Lorem ipsum dolor sit amet, consectetur Praesent ut ultrices sit
40
Kit

Der beste Wert ist derjenige, der für die in der zugrunde liegenden Domäne definierten Daten richtig ist.

Für einige Domains ist VARCHAR(10) das richtige Attribut für Name, für andere Domains ist VARCHAR(255) möglicherweise die beste Wahl.

30
Oded

Wenn Sie die Antwort von a_horse_with_no_name hinzufügen, könnten Sie Folgendes von Interesse finden ...

es macht keinen Unterschied, ob Sie eine Spalte als VARCHAR (100) oder VACHAR (500) deklarieren.

-- try to create a table with max varchar length
drop table if exists foo;
create table foo(name varchar(65535) not null)engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length - 2 bytes for the length
drop table if exists foo;
create table foo(name varchar(65533) not null)engine=innodb;

Executed Successfully

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65533))engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65532))engine=innodb;

Executed Successfully

Vergessen Sie nicht das/die Längenbyte (s) und das nullfähige Byte:

name varchar(100) not null hat eine Länge von 1 Byte + bis zu 100 Zeichen (latin1)

name varchar(500) not null hat eine Länge von 2 Bytes + bis zu 500 Zeichen (latin1)

name varchar(65533) not null hat eine Länge von 2 Byte + bis zu 65533 Zeichen (latin1)

name varchar(65532) hat eine Länge von 2 Byte + bis zu 65532 Zeichen (latin1) + 1 Null-Byte

Hoffe das hilft :)

14
Jon Black

Wenden Sie sich immer an Ihren Business-Domain-Experten. Wenn Sie es sind, suchen Sie nach einem Industriestandard. Wenn es sich bei der fraglichen Domain beispielsweise um den Familiennamen (Nachnamen) einer natürlichen Person handelt, gehe ich für ein Unternehmen im Vereinigten Königreich zum Katalog der britischen Govtalk-Datenstandards für Personeninformationen und entdecke, dass es sich um einen Familiennamen handelt wird zwischen 1 und 35 Zeichen sein.

6
onedaywhen

Ich habe dies in letzter Zeit nicht überprüft, aber ich wusste in der Vergangenheit mit Oracle, dass der JDBC-Treiber während der Abfrageausführung einen Teil des Speichers reservieren würde, um die zurückkommende Ergebnismenge zurückzuhalten. Die Größe des Speicherbereichs hängt von den Spaltendefinitionen und der Abrufgröße ab. Die Länge der varchar2-Spalten beeinflusst also, wie viel Speicher reserviert ist. Dies verursachte vor Jahren schwerwiegende Leistungsprobleme, da wir immer varchar2 (4000) (das Maximum zu der Zeit) verwendeten und die Speicherbereinigung viel weniger effizient war als heute.

3
user1041892