Gibt es in SQL Server 2005 Nachteile, wenn alle Zeichenfelder nvarchar (MAX) erstellt werden, anstatt eine Länge explizit anzugeben, z. B. nvarchar (255)? (Abgesehen von der offensichtlichen Tatsache, dass Sie die Feldlänge auf Datenbankebene nicht begrenzen können)
sql
sql-server
sql-server-2005
stucampbell
quelle
quelle
Antworten:
Dieselbe Frage wurde in den MSDN-Foren gestellt:
Aus dem ursprünglichen Beitrag (viel mehr Informationen dort):
quelle
N/VARCHAR(MAX)
" gelesen, da es eine zusätzliche Verarbeitung gibt "nur wenn die Größe 8000 überschreitet". Somit entstehen Ihnen die Kosten nur bei Bedarf und Ihre Datenbank ist weniger restriktiv . Lese ich das falsch Scheint, als würden Sie fast immerN/VARCHAR(MAX)
lieber wollen alsN/VARCHAR(1-8000)
...sp_tableoptions
: msdn.microsoft.com/en-us/library/ms173530.aspx . VARCHAR (255) -Typen können auch aus der Reihe verschoben werden. Der erwähnte "Overhead" kann für MAX und 255 genau gleich sein. Er vergleicht MAX-Typen mit TEXT-Typen, wenn sie sich nach Belieben unterscheiden (völlig andere zu manipulierende API). andere Lagerung etc). Die tatsächlichen Unterschiede werden nicht erwähnt: kein Index, keine Online-Operationen für MAX-TypenEs ist eine faire Frage und er hat abgesehen von den offensichtlichen ...
Zu den Nachteilen können gehören:
Auswirkungen auf die Leistung Das Abfrageoptimierungsprogramm verwendet die Feldgröße, um den effizientesten Ausführungsplan zu bestimmen
"1. Die Speicherplatzzuweisung in Erweiterungen und Seiten der Datenbank ist flexibel. Wenn Sie also mithilfe der Aktualisierung Informationen zum Feld hinzufügen, muss Ihre Datenbank einen Zeiger erstellen, wenn die neuen Daten länger als die zuvor eingefügten sind. Dies würden die Datenbankdateien tun fragmentiert werden = geringere Leistung in fast allem, 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 in Ihre Datenbank integriert werden können. Unvorhersehbares Datenwachstum Mögliche Sicherheitsprobleme, z. B. Sie könnten ein System zum Absturz bringen, indem Sie den gesamten Speicherplatz belegen
Hier gibt es einen guten Artikel: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html
quelle
varchar(max)
.Basierend auf dem Link in der akzeptierten Antwort scheint es, dass:
100 Zeichen, die in einem
nvarchar(MAX)
Feld gespeichert sind, werden nicht anders als 100 Zeichen in einemnvarchar(100)
Feld gespeichert. Die Daten werden inline gespeichert, und Sie haben nicht den Aufwand, Daten "außerhalb der Zeile" zu lesen und zu schreiben. Also keine Sorge.Wenn die Größe größer als 4000 ist, werden die Daten automatisch "außerhalb der Zeile" gespeichert, was Sie möchten. Also auch dort keine Sorgen.
Jedoch...
nvarchar(MAX)
Spalte erstellen . Sie können die Volltextindizierung verwenden, jedoch keinen Index für die Spalte erstellen, um die Abfrageleistung zu verbessern. Für mich besiegelt dies den Deal ... es ist ein klarer Nachteil, immer nvarchar (MAX) zu verwenden.Fazit:
Wenn Sie eine Art "universelle Zeichenfolgenlänge" in Ihrer gesamten Datenbank wünschen, die indiziert werden kann und die keinen Speicherplatz und keine Zugriffszeit verschwendet, können Sie diese verwenden
nvarchar(4000)
.quelle
nvarchar(max)
ganze Zeit verwenden - wiestring
in C #? - aber Punkt 3) (das Indexproblem) gibt die Antwort.nvarchar(4000)
Manchmal möchten Sie, dass der Datentyp den darin enthaltenen Daten einen Sinn verleiht.
Angenommen, Sie haben eine Spalte, die eigentlich nicht länger als beispielsweise 20 Zeichen sein sollte. Wenn Sie diese Spalte als VARCHAR (MAX) definieren, könnte eine nicht autorisierte Anwendung eine lange Zeichenfolge in sie einfügen, und Sie würden es nie erfahren oder auf irgendeine Weise verhindern können.
Wenn Ihre Anwendung diese Zeichenfolge das nächste Mal verwendet, wird unter der Annahme, dass die Länge der Zeichenfolge für die von ihr dargestellte Domäne bescheiden und angemessen ist, ein unvorhersehbares und verwirrendes Ergebnis angezeigt.
quelle
Ich habe einige Artikel überprüft und daraus ein nützliches Testskript gefunden : http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Dann wurde es geändert, um zwischen NVARCHAR (10) und NVARCHAR (4000) und NVARCHAR (MAX) zu vergleichen ) und ich finde keinen Geschwindigkeitsunterschied bei Verwendung bestimmter Zahlen, sondern bei Verwendung von MAX. Sie können selbst testen. Ich hoffe das hilft.
quelle
Betrachten Sie es als eine weitere Sicherheitsstufe. Sie können Ihre Tabelle ohne Fremdschlüsselbeziehungen entwerfen - absolut gültig - und sicherstellen, dass zugehörige Entitäten vollständig auf der Geschäftsschicht vorhanden sind. Fremdschlüssel gelten jedoch als gute Entwurfspraxis, da sie eine weitere Einschränkungsebene hinzufügen, falls auf der Geschäftsebene etwas durcheinander kommt. Gleiches gilt für die Begrenzung der Feldgröße und die Nichtverwendung von varchar MAX.
quelle
Ein Grund, KEINE Maximal- oder Textfelder zu verwenden, besteht darin, dass Sie auch mit SQL Server Enterprise Edition keine Online- Indexwiederherstellungen durchführen können, dh REBUILD WITH ONLINE = ON.
quelle
Das einzige Problem, das ich fand, war, dass wir unsere Anwendungen auf SQL Server 2005 entwickeln und in einem Fall SQL Server 2000 unterstützen müssen. Ich habe gerade gelernt, wie schwierig es ist, dass SQL Server 2000 die MAX-Option für varchar oder nicht mag nvarchar.
quelle
Eine schlechte Idee, wenn Sie wissen, dass das Feld in einem festgelegten Bereich von beispielsweise 5 bis 10 Zeichen liegt. Ich denke, ich würde max nur verwenden, wenn ich nicht sicher wäre, wie lang es sein würde. Zum Beispiel würde eine Telefonnummer niemals mehr als eine bestimmte Anzahl von Zeichen sein.
Können Sie ehrlich sagen, dass Sie sich über die ungefähren Längenanforderungen für jedes Feld in Ihrer Tabelle nicht sicher sind?
Ich verstehe Ihren Standpunkt jedoch - es gibt einige Felder, die ich sicherlich in Betracht ziehen würde, varchar (max) zu verwenden.
Interessanterweise fassen die MSDN-Dokumente es ziemlich gut zusammen:
Hier gibt es eine interessante Diskussion zu diesem Thema .
quelle
Die Aufgabe der Datenbank besteht darin, Daten so zu speichern, dass sie vom Unternehmen verwendet werden können. Ein Teil der Nützlichkeit dieser Daten besteht darin, sicherzustellen, dass sie aussagekräftig sind. Wenn Sie jemandem erlauben, eine unbegrenzte Anzahl von Zeichen für seinen Vornamen einzugeben, werden keine aussagekräftigen Daten sichergestellt.
Es ist eine gute Idee, diese Einschränkungen in die Geschäftsschicht zu integrieren, dies stellt jedoch nicht sicher, dass die Datenbank intakt bleibt. Die einzige Möglichkeit, um sicherzustellen, dass die Datenregeln nicht verletzt werden, besteht darin, sie auf der niedrigstmöglichen Ebene in der Datenbank durchzusetzen.
quelle
Ein Problem ist, dass MAX nicht immer funktioniert, wenn Sie mit mehreren Versionen von SQL Server arbeiten müssen. Wenn Sie also mit älteren DBs oder einer anderen Situation arbeiten, die mehrere Versionen umfasst, sollten Sie sehr vorsichtig sein.
quelle
Wie oben erwähnt, handelt es sich in erster Linie um einen Kompromiss zwischen Speicher und Leistung. Zumindest in den meisten Fällen.
Es gibt jedoch mindestens einen weiteren Faktor, der bei der Auswahl von n / varchar (Max) gegenüber n / varchar (n) berücksichtigt werden sollte. Werden die Daten indiziert (z. B. ein Nachname)? Da die MAX-Definition als LOB betrachtet wird, steht für die Indizierung nichts zur Verfügung, was als MAX definiert ist. und ohne Index wird jede Suche, bei der die Daten als Prädikat in einer WHERE-Klausel enthalten sind, zu einem vollständigen Tabellenscan gezwungen. Dies ist die schlechteste Leistung, die Sie für die Suche nach Daten erzielen können.
quelle
1) Der SQL Server muss mehr Ressourcen (zugewiesener Speicher und CPU-Zeit) verwenden, wenn er mit nvarchar (max) und nvarchar (n) arbeitet, wobei n eine feldspezifische Zahl ist.
2) Was bedeutet das für die Leistung?
Unter SQL Server 2005 habe ich 13.000 Datenzeilen aus einer Tabelle mit 15 nvarchar (max) -Spalten abgefragt. Ich habe die Abfragen wiederholt zeitlich festgelegt und dann die Spalten in nvarchar (255) oder weniger geändert.
Die Abfragen vor der Optimierung betrugen durchschnittlich 2,0858 Sekunden. Die Abfragen nach der Änderung wurden in durchschnittlich 1,90 Sekunden zurückgegeben. Das waren ungefähr 184 Millisekunden Verbesserung der grundlegenden select * -Abfrage. Das ist eine Verbesserung um 8,8%.
3) Meine Ergebnisse stimmen mit einigen anderen Artikeln überein, die darauf hinwiesen, dass es einen Leistungsunterschied gab. Abhängig von Ihrer Datenbank und der Abfrage kann der Prozentsatz der Verbesserung variieren. Wenn Sie nicht viele Benutzer gleichzeitig oder sehr viele Datensätze haben, ist der Leistungsunterschied für Sie kein Problem. Der Leistungsunterschied nimmt jedoch zu, wenn mehr Datensätze und gleichzeitige Benutzer zunehmen.
quelle
Ich hatte ein udf, das Strings auffüllte und die Ausgabe auf varchar (max) stellte. Wenn dies direkt verwendet wurde, anstatt auf die geeignete Größe für die einzustellende Säule zurückzuschlagen, war die Leistung sehr schlecht. Am Ende habe ich das udf mit einer großen Note auf eine beliebige Länge gebracht, anstatt mich darauf zu verlassen, dass alle Aufrufer des udf die Zeichenfolge auf eine kleinere Größe umwandeln.
quelle
Legacy-Systemunterstützung. Wenn Sie ein System haben, das die Daten verwendet und eine bestimmte Länge erwartet wird, ist die Datenbank ein guter Ort, um die Länge zu erzwingen. Dies ist nicht ideal, aber Legacy-Systeme sind manchmal nicht ideal. = P.
quelle
Wenn alle Daten in einer Zeile (für alle Spalten) niemals vernünftigerweise 8000 oder weniger Zeichen annehmen würden, sollte das Design auf der Datenschicht dies erzwingen.
Das Datenbankmodul ist viel effizienter und hält alles aus dem Blob-Speicher heraus. Je kleiner Sie eine Zeile einschränken können, desto besser. Je mehr Zeilen Sie auf einer Seite speichern können, desto besser. Die Datenbank bietet nur dann eine bessere Leistung, wenn auf weniger Seiten zugegriffen werden muss.
quelle
Meine Tests haben gezeigt, dass es Unterschiede bei der Auswahl gibt.
quelle
Interessanter Link: Warum ein VARCHAR verwenden, wenn Sie TEXT verwenden können?
Es geht um PostgreSQL und MySQL, daher ist die Leistungsanalyse unterschiedlich, aber die Logik für "explizite Aussagen" gilt immer noch: Warum sollten Sie sich zwingen, sich immer um etwas zu kümmern, das nur einen kleinen Prozentsatz der Zeit relevant ist? Wenn Sie eine E-Mail-Adresse in einer Variablen gespeichert haben, verwenden Sie eine Zeichenfolge, keine auf 80 Zeichen beschränkte Zeichenfolge.
quelle
Der Hauptnachteil, den ich sehen kann, ist, dass wir Folgendes haben:
Welches gibt Ihnen die meisten Informationen zu den Daten, die für die Benutzeroberfläche benötigt werden?
Diese
Oder dieses?
quelle
Ein Nachteil besteht darin, dass Sie eine unvorhersehbare Variable entwerfen und die interne SQL Server-Datenstruktur, die sich zunehmend aus Zeilen, Seiten und Ausmaßen zusammensetzt, wahrscheinlich ignorieren, anstatt sie zu nutzen.
Was mich über die Ausrichtung der Datenstruktur nachdenken lässt in C und dass es im Allgemeinen als eine gute Sache (TM) angesehen wird, sich der Ausrichtung bewusst zu sein. Ähnliche Idee, anderer Kontext.
MSDN-Seite für Seiten und Bereiche
MSDN-Seite für Zeilenüberlaufdaten
quelle
Zuerst habe ich darüber nachgedacht, dann aber noch einmal. Es gibt Auswirkungen auf die Leistung, aber es dient auch als Dokumentationsform, um eine Vorstellung davon zu bekommen, wie groß die Felder tatsächlich sind. Und es wird erzwungen, wenn sich diese Datenbank in einem größeren Ökosystem befindet. Meiner Meinung nach ist der Schlüssel freizügig, aber nur im Rahmen der Vernunft.
ok, hier sind meine Gefühle einfach zum Thema Geschäfts- und Datenschichtlogik. Es hängt davon ab, ob Ihre Datenbank eine gemeinsam genutzte Ressource zwischen Systemen ist, die Geschäftslogik gemeinsam nutzen. Dann scheint es natürlich ein natürlicher Ort zu sein, diese Logik durchzusetzen, aber es ist nicht die BESTE Methode, dies zu tun. Die BESTE Methode besteht darin, eine API bereitzustellen, die dies ermöglicht Die zu testende Interaktion hält die Geschäftslogik dort, wo sie hingehört, hält die Systeme entkoppelt und hält Ihre Ebenen innerhalb eines Systems entkoppelt. Wenn Ihre Datenbank jedoch nur eine Anwendung bedienen soll, lassen Sie uns AGILE überlegen, was jetzt wahr ist. Design für jetzt. Wenn ein solcher Zugriff erforderlich ist, stellen Sie eine API für diese Daten bereit.
Dies ist natürlich nur das Ideal. Wenn Sie mit einem vorhandenen System arbeiten, ist es wahrscheinlich, dass Sie dies zumindest kurzfristig anders machen müssen.
quelle
Dies führt zu einem Leistungsproblem, obwohl es möglicherweise nie zu tatsächlichen Problemen kommt, wenn Ihre Datenbank klein ist. Jeder Datensatz nimmt mehr Speicherplatz auf der Festplatte ein und die Datenbank muss mehr Sektoren der Festplatte lesen, wenn Sie viele Datensätze gleichzeitig durchsuchen. Beispielsweise könnte ein kleiner Datensatz 50 für einen Sektor und ein großer Datensatz für 5 passen. Mit dem großen Datensatz müssten Sie zehnmal so viele Daten von der Festplatte lesen.
quelle
nvarchar(max)
Spalte gespeicherte Zeichenfolge mit der Länge 100 benötigt nicht mehr Speicherplatz als in einernvarchar(100)
Spalte.Dies erschwert das Bildschirmdesign, da Sie nicht mehr vorhersagen können, wie breit Ihre Steuerelemente sein sollten.
quelle