Gibt es in SQL Server 2005 irgendwelche Nachteile, wenn man alle Zeichenfelder zu nvarchar(MAX) macht, anstatt explizit eine Länge anzugeben, z. B. nvarchar(255)? (Abgesehen von dem offensichtlichen Nachteil, dass man die Feldlänge nicht auf Datenbankebene begrenzen kann)
Antworten
Zu viele Anzeigen?Die gleiche Frage wurde in den MSDN-Foren gestellt:
Aus dem Original-Posting (dort gibt es viel mehr Informationen):
Wenn Sie Daten in einer VARCHAR(N)-Spalte speichern, werden die Werte physisch auf dieselbe Weise gespeichert. Wenn Sie sie jedoch in einer VARCHAR(MAX)-Spalte speichern, werden die Daten hinter dem Bildschirm als TEXT-Wert behandelt. Es ist also eine zusätzliche Verarbeitung erforderlich, wenn Sie mit einem VARCHAR(MAX)-Wert arbeiten. (nur wenn die Größe 8000 überschreitet)
VARCHAR(MAX) oder NVARCHAR(MAX) wird als "großer Werttyp" betrachtet. Große Werttypen werden in der Regel "außerhalb der Zeile" gespeichert. Das bedeutet, dass die Datenzeile einen Zeiger auf einen anderen Ort hat, an dem der "große Wert" gespeichert ist...
Aus dem in der akzeptierten Antwort angegebenen Link geht hervor, dass:
-
100 Zeichen gespeichert in einer
nvarchar(MAX)
Feld wird nicht anders als 100 Zeichen in einemnvarchar(100)
Feld - die Daten werden inline gespeichert, und Sie haben nicht den Overhead des Lesens und Schreibens von Daten "außerhalb der Zeile". Sie brauchen sich also keine Sorgen zu machen. -
Wenn die Größe größer als 4000 ist, werden die Daten automatisch "außerhalb der Zeile" gespeichert, was ja auch gewünscht ist. Auch hier besteht also kein Grund zur Sorge.
Aber...
- Sie können keinen Index für eine
nvarchar(MAX)
Spalte. Sie können die Volltextindizierung verwenden, aber Sie können keinen Index für die Spalte erstellen, um die Abfrageleistung zu verbessern. Für mich ist das ein entscheidender Nachteil, wenn man immer nvarchar(MAX) verwendet.
Schlussfolgerung:
Wenn Sie eine Art "universelle Zeichenkettenlänge" für Ihre gesamte Datenbank wollen, die indiziert werden kann und die keinen Platz und keine Zugriffszeit verschwendet, dann könnten Sie verwenden nvarchar(4000)
.
Es ist eine berechtigte Frage und er hat neben dem Offensichtlichen auch gesagt
Zu den Nachteilen könnten gehören:
Auswirkungen auf die Leistung Der Abfrageoptimierer verwendet die Feldgröße, um den effizientesten Ausführungsplan zu ermitteln.
"1) Die Speicherplatzzuweisung in Erweiterungen und Seiten der Datenbank ist flexibel. Beim Hinzufügen von Informationen zu einem Feld mittels Update müsste Ihre Datenbank also einen Zeiger erstellen, wenn die neuen Daten länger sind als die zuvor eingefügten. Dadurch würden die Datenbankdateien fragmentiert werden = geringere Leistung in fast allen Bereichen, vom Index bis zum Löschen, Aktualisieren und Einfügen. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx
Auswirkungen auf die Integration - für andere Systeme ist es schwierig zu wissen, wie sie mit Ihrer Datenbank integriert werden können Unvorhersehbares Wachstum der Daten Mögliche Sicherheitsprobleme, z. B. könnten Sie ein System zum Absturz bringen, wenn Sie den gesamten Speicherplatz belegen
Es gibt einen guten Artikel hier: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html
Manchmal möchte man, dass der Datentyp den darin enthaltenen Daten einen gewissen Sinn aufzwingt.
Nehmen wir an, Sie haben eine Spalte, die nicht länger als, sagen wir, 20 Zeichen sein sollte. Wenn Sie diese Spalte als VARCHAR(MAX) definieren, könnte eine bösartige Anwendung eine lange Zeichenkette in diese Spalte einfügen, ohne dass Sie es merken oder eine Möglichkeit haben, dies zu verhindern.
Wenn Ihre Anwendung diese Zeichenkette das nächste Mal verwendet und davon ausgeht, dass die Länge der Zeichenkette bescheiden und angemessen für den Bereich ist, den sie repräsentiert, werden Sie ein unvorhersehbares und verwirrendes Ergebnis erhalten.
Ich habe mir einige Artikel angesehen und daraus ein nützliches Testskript gefunden: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Dann änderte es, um zwischen NVARCHAR(10) vs NVARCHAR(4000) vs NVARCHAR(MAX) zu vergleichen, und ich finde keinen Geschwindigkeitsunterschied bei der Verwendung von angegebenen Zahlen, aber bei der Verwendung von MAX. Sie können das selbst testen. Hoffentlich hilft das.
SET NOCOUNT ON;
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
@StartTime DATETIME;
--=====
SELECT @startTime = GETDATE();
SELECT TOP 1000000
@SomeString = 'ABC'
FROM master.sys.all_columns ac1,
master.sys.all_columns ac2;
SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
@StartTime DATETIME;
SELECT @startTime = GETDATE();
SELECT TOP 1000000
@SomeString = 'ABC'
FROM master.sys.all_columns ac1,
master.sys.all_columns ac2;
SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
@StartTime DATETIME;
SELECT @startTime = GETDATE();
SELECT TOP 1000000
@SomeString = 'ABC'
FROM master.sys.all_columns ac1,
master.sys.all_columns ac2;
SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
- See previous answers
- Weitere Antworten anzeigen