Gibt es Nachteile bei der Verwendung von nvarchar (MAX)?


342

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)


1
Ich verstehe nur nicht, warum Sie jemanden einen Namen mit mehr als 8000 Zeichen eingeben lassen möchten.
DForck42

2
Die gleiche Logik kann auf Programmiersprachen angewendet werden. Warum nicht für alle unsere Daten zur alten VB6-Variante zurückkehren? Ich denke nicht, dass es notwendigerweise schlecht ist, Checks and Balances an mehr als einem Ort zu haben.
Matt Spradley


10
Ihr Update sollte eine eigene Antwort auf diese Frage sein.
Johann

Die Antwort auf die Frage wurde zur richtigen Antwort verschoben, da der ursprüngliche Autor dies nicht getan hat. stackoverflow.com/a/35177895/10245 Ich denke , 7 Jahre sind genug Zeit :-)
Tim Abell

Antworten:


153

Dieselbe Frage wurde in den MSDN-Foren gestellt:

Aus dem ursprünglichen Beitrag (viel mehr Informationen dort):

Wenn Sie Daten in einer VARCHAR (N) -Spalte speichern, werden die Werte auf dieselbe Weise physisch gespeichert. Wenn Sie es jedoch in einer VARCHAR (MAX) -Spalte speichern, werden die Daten hinter dem Bildschirm als TEXT-Wert behandelt. Daher ist beim Umgang mit einem VARCHAR (MAX) -Wert eine zusätzliche Verarbeitung erforderlich. (nur wenn die Größe 8000 überschreitet)

VARCHAR (MAX) oder NVARCHAR (MAX) wird als "Typ mit großem Wert" betrachtet. Große Werttypen werden normalerweise "außerhalb der Zeile" gespeichert. Dies bedeutet, dass die Datenzeile einen Zeiger auf eine andere Stelle hat, an der der 'große Wert' gespeichert ist ...


2
Sollte die Frage also sein, gibt es einen Unterschied zwischen der Verwendung von N / VARCHAR (MAX) und N / TEXT?
Nicht geschnitten

18
Wenn ich mich richtig erinnere, werden sie nicht nur außerhalb der Zeile gespeichert, wenn die Größe 8 KB überschreitet?
Sam Schutte

79
Ich habe die Antwort als "Nein, es gibt keinen Nachteil bei der Verwendung 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 immer N/VARCHAR(MAX)lieber wollen als N/VARCHAR(1-8000)...
Kent Boogaart

1
Toter Link oben - der Arbeitslink für die Frage auf MSDN ist social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/…
Jagd

68
Leider hat diese Antwort eine Reihe von Problemen. Es lässt die 8k-Grenze wie eine magische Zahl erscheinen, ist nicht wahr, der Wert wird aufgrund weiterer Faktoren aus der Zeile verschoben , einschließlich 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-Typen
Remus Rusanu

50

Es 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


4
+1 Für die Auswirkungen auf Integration und Sicherheit. Dies ist ein origineller Blickwinkel, den Sie berücksichtigen sollten, wenn die meisten anderen Antworten über die Leistung sprechen. Im Zusammenhang mit den Auswirkungen auf die Integration würden Tools (z. B. Berichtersteller oder Formularentwickler), die Metadaten verwenden, um angemessene Standardsteuerelementgrößen bereitzustellen, viel mehr Arbeit erfordern, wenn alle Spalten vorhanden wären varchar(max).
Desillusioniert

Die Integration per Datenbank ist das Lächerlichste, was ich weiß. Wenn es nur einmal importiert wird, können Sie die Daten zuvor mit der LEN-Funktion überprüfen.
Maxim

30

Basierend auf dem Link in der akzeptierten Antwort scheint es, dass:

  1. 100 Zeichen, die in einem nvarchar(MAX)Feld gespeichert sind, werden nicht anders als 100 Zeichen in einem nvarchar(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.

  2. 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...

  1. Sie können keinen Index für eine 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).


1
Zu Ihrer Information, dies war eine Änderung, die der ursprünglichen Frage hinzugefügt wurde, die als Antwort hätte veröffentlicht werden sollen
Tim Abell

1
Danke, für mich ist dies die endgültige Antwort. Ich habe mich das gleiche gefragt - warum nicht die nvarchar(max)ganze Zeit verwenden - wie stringin C #? - aber Punkt 3) (das Indexproblem) gibt die Antwort.
SQL Police

1
Eine Bearbeitung hinzugefügt. Als eine Art "universelle Stringlänge" können Sie immer verwendennvarchar(4000)
SQL Police

@ SQLGeorge Sehen Sie diese ausgezeichnete Antwort von Martin Smith über die Auswirkungen auf die Abfrageleistung von deklarierenden Spalten, die breiter sind als jemals zuvor
billinkc

@ Billinkc Danke, das ist ein großartiger Artikel. OK, die Größe wirkt sich also tatsächlich auf die Leistung aus. Ich werde die Antwort erneut bearbeiten.
SQL Police

28

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.


9
Ich stimme dem und einigen anderen Kommentaren zu, aber ich behaupte immer noch, dass dies in der Verantwortung der Geschäftsschicht liegt. Wenn es die Datenbankebene erreicht, sollte es einen Gruß auslösen und den Wert speichern, egal wie lächerlich lang er ist. Ich denke, was hier wirklich im Spiel ist, ist, dass ich in 90% der Fälle, in denen ein Entwickler varchar (255) spezifiziert, nicht wirklich 255 Zeichen, sondern einen nicht spezifizierten mittleren Längenwert vorhabe. Und angesichts des Kompromisses zwischen unangemessen großen Werten in meiner Datenbank und unvorhergesehenen Ausnahmen werde ich die großen Werte nehmen.
Chris B. Behrens

4
Wenn sie VARCHAR (255) angeben, um eine unbekannte Länge anzugeben, ist dies ihre Schuld daran, dass sie nicht richtig recherchieren, was sie entwerfen. Die Lösung besteht darin, dass der Entwickler seine Arbeit erledigt, nicht dass die Datenbank unangemessene Werte zulässt.
Tom H

10
nicht hilfreich für den Autor. Er hat diese Frage, auf die Sie eine Antwort gegeben haben, ausdrücklich ausgeschlossen.
Usr

6
@ Chris B Behrens: Ich bin anderer Meinung; Das Datenbankschema ist Teil der Geschäftslogik. Die Auswahl von Tabellen, Beziehungen, Feldern und Datentypen hängt von der Geschäftslogik ab - und es lohnt sich, das RDBMS zu verwenden, um die Regeln dieser Geschäftslogik durchzusetzen. Aus einem Grund ist es sehr selten, dass nur eine Anwendungsebene auf die Datenbank zugreift. Beispielsweise verfügen Sie möglicherweise über Tools zum Importieren und Extrahieren von Daten, die die Hauptgeschäftsebene umgehen. Dies bedeutet, dass Sie die Datenbank wirklich benötigen, um die Regeln durchzusetzen.
Vince Bowdren

1
Wenn Sie keine langen Zeichenfolgen speichern müssen oder möchten, ist es besser, den Daten Sinn zu verleihen. Wenn Sie beispielsweise ein PostCode-Feld speichern, lassen Sie jemanden Hunderte oder Tausende von Zeichen eingeben, wenn es maximal 10 sein sollte. - Die maximale Größe sollte auf allen Ebenen, Client, Geschäftsschicht UND Datenbank überprüft werden. Wenn Sie einen Model First-Ansatz verwenden, z. B. mit C # und Entity Framework, können Sie die maximale Größe des Modells definieren und auf die Datenbank, die Geschäftslogik und die Client-Validierung anwenden lassen (z. B. jquery-Validierung). Verwenden Sie nvarchar (max) nur, wenn es wirklich benötigt wird
Peter Kerr

21

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.

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

4
Das ist interessant. Auf meiner Box scheint die MAX 4x langsamer zu sein.
Stucampbell

4
Neue Ergebnisse unter SQL Server 2012: 10 ist zweimal langsamer als 4 KB und MAX ist 5,5 Mal langsamer als 4 KB.
Cassandrad

1
Die meiste Zeit ist die implizite Besetzung von varchar nach nvarchar (max). Versuchen Sie Folgendes: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (max) = N'ABC ', \ @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 ()); Musste \ vor Variablen einfügen, um es zu posten.
Kvasi

4
SQL Server 2014 auf SSD: 150, 156, 716 (10, 4000, MAX).
Maxim

2
Vielen Dank, dass Sie dieser Diskussion einige reelle Zahlen hinzugefügt haben. Wir vergessen oft, dass das Erstellen eines Testfalls der schnellste Weg zur Einsicht ist.
David C

13

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.


8

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.


1
Dieselbe Einschränkung gilt für den Feldtyp TEXT. Sie sollten daher weiterhin VARCHAR (MAX) anstelle von TEXT verwenden.
Will Shaver

Aus diesem Grund konnten wir unseren Clustered-Index nicht neu erstellen. Es kostete uns viel Speicherplatz, bis wir die Spalte in eine eigene Tabelle extrahieren konnten (wir konnten es uns nicht leisten, die Tabelle länger als 7 Sekunden zu sperren)
Choco Smith,

4

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.


2
Warum also nicht einfach auf dem kleinsten gemeinsamen Nenner entwickeln?
Binki

4

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:

Verwenden Sie varchar, wenn die Größe der Spaltendateneinträge erheblich variiert. Verwenden Sie varchar (max), wenn die Größe der Spaltendateneinträge erheblich variiert und die Größe möglicherweise 8.000 Byte überschreitet.

Hier gibt es eine interessante Diskussion zu diesem Thema .


2
Für Dinge wie Telefonnummern wäre es viel angenehmer, ein Zeichenfeld anstelle von Varchar zu verwenden. Solange Sie einen Standard in Ihrem Speicher beibehalten und sich nicht um Telefonnummern aus verschiedenen Ländern kümmern müssen, sollten Sie niemals ein variables Feld für eine Telefonnummer (10 ohne Formatierung) oder Postleitzahl (5) benötigen oder 9-10, wenn Sie die letzten vier Ziffern hinzufügen) usw.
TheTXI

Ich bezog mich auf Telefonnummern, deren Länge variieren kann. Vielleicht sollte ich das in die Antwort aufnehmen. Für alles, was eine feste Länge hat, würde ich ein Zeichenfeld verwenden.
RichardOD

Oder vielleicht sollte ich in meinem Kommentar nchar oder char sagen. :-)
RichardOD

2
Die Anzahl der Zeichen in einer Telefonnummer ist so ziemlich eine Geschäftsanforderung. Wenn Sie den internationalen Standardcode zusammen mit der Nummer speichern müssten, könnten es mehr als 10 sein. Oder ein Teil der Welt könnte mehr als 10 Ziffern für eine Telefonnummer haben. Stellen Sie sich den Fall des Übergangs von IPV4 zu IPV6 vor. Niemand hätte argumentiert, dass wir in den guten alten IPV4-Tagen mehr als 12 Ziffern brauchten. Es kann sein, dass es nicht gilt, wenn IPV6 vorherrscht. Dies ist wiederum eine Änderung der Geschäftsregeln über einen bestimmten Zeitraum. Wie gesagt, Veränderung ist die einzige Konstante, die wir erwarten können :)
Bleistiftscheibe

2
Gehen Sie vorsichtig davon aus, dass Sie wissen, wie viele Zeichen sich in einem Telefonnummernfeld befinden können oder welche Art von Zeichen sie sein werden. Wenn das System diese Daten nicht zum tatsächlichen Wählen verwendet (in diesem Fall müssen Sie die Formate genau beachten), kann der Benutzer dort zu Unrecht unerwartet lange Zeichenfolgen einfügen, z. B. "0123 456 78910, Empfang an der Erweiterung um Erweiterung 45 bitten und dann an James übertragen".
Vince Bowdren

4

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.


6
IMO, die Datenlängenbeschränkungen basieren ausschließlich auf den Geschäftsregeln, die sich im Laufe der Zeit ändern können, wenn die Anwendung wächst. Das Ändern von Geschäftsregeln auf Geschäftslogik ist einfacher als auf DB-Ebene. Daher denke ich, dass die Datenbank flexibel genug sein sollte und nicht an Geschäftsregeln wie die maximal zulässige Länge des Vornamens gebunden sein sollte, was sehr stark von dem Teil der Welt abhängt, in dem Ihr Benutzer lebt.
Bleistiftscheibe

3

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.


Ich denke, die unausgesprochene Annahme des OP ist, dass er sich ausschließlich mit Instanzen ab 2005 befasst und dass seine Apps nicht mit 2000 (oder, ack, niedrigeren) Versionen funktionieren müssen. Ich stimme Ihnen voll und ganz zu, wenn die älteren Versionen unterstützt werden müssen!
John Rudy

John Rudy: Ich würde mir vorstellen, dass dies der Fall ist. Ich weiß nur, dass ich selbst auf diese Hürden gestoßen bin, als ich nicht dachte, dass ich es tun würde.
TheTXI

Tatsächlich ist dies aufgrund von SQL CE 4, das keine MAX-Spaltentypen unterstützt, immer noch ein weit verbreitetes Problem bei modernen Geräten, sodass die Interoperabilität problematisch ist.
JohnC

3

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.


2

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.


1

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.


1

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.


1

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.


1

Meine Tests haben gezeigt, dass es Unterschiede bei der Auswahl gibt.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;

0

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.


1
Das ist vergleichbar mit der Argumentation, dass Sie keine Kontrollbeschränkungen haben sollten, um sicherzustellen, dass das Alter einer Person keine negative Zahl ist.
Jonathan Allen

Ich sehe einen Unterschied zwischen Datenkorrektheit und Leistungsoptimierung.
Orip

0

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

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Oder dieses?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

3
Ich würde es vorziehen, wenn die Geschäftslogik mir sagt, dass ein Firmenname maximal 50 Zeichen lang sein kann, anstatt eine Datenbanktabelle für diese Informationen zu verwenden.
Khan

Ich stimme Jeff zu. Ich denke nicht, dass der Persistenzspeicher der richtige Ort ist, um Ihre Geschäftsregeln zu definieren. Und in einer mehrschichtigen Architektur würde Ihre Benutzeroberfläche nicht einmal über die Persistenzschicht Bescheid wissen.
Stucampbell

Es sei denn, Sie verwenden einen Wert, der auf eine bestimmte Größe beschränkt ist, z. B. den ISO-Code für das Land.
Ben

2
Was hat das mit einem Table Def zu tun? Sie können immer noch Geschäftslogik haben. Ich denke, Ihr Standpunkt macht keinen Sinn, wenn es darum geht, wie ein Tisch gestaltet ist. Wenn Sie dennoch eine Definition in Ihrer Geschäftsschicht entwerfen möchten, sollten Sie dies auch tun. Was jedoch sinnvoller wäre, ist die Verwendung eines gespeicherten Prozesses in der Geschäftsschicht. kein Tisch def ??
Carlos Martini

1
Es scheint unbeliebt, aber ich stimme Carlos zu. Wenn die Datenbank eine maximale Größe festlegt, können Sie sich in allen Schichten, die Sie darauf aufbauen, wohlfühlen, mit denen Sie wahrscheinlich zu tun haben. Dies ist besonders wichtig, wenn mehrere Systeme in Ihre Datenbank schreiben.
Tim Abell

0

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


0

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.


-1

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.


5
-1. Eine in einer nvarchar(max)Spalte gespeicherte Zeichenfolge mit der Länge 100 benötigt nicht mehr Speicherplatz als in einer nvarchar(100)Spalte.
Martin Smith

Was Sie beschreiben, ist richtig, wenn die Größe der gespeicherten Daten größer ist. Bei dieser Frage geht es jedoch darum, ob der Datentyp Auswirkungen auf die Leistung oder andere Überlegungen hat.

-2

Dies erschwert das Bildschirmdesign, da Sie nicht mehr vorhersagen können, wie breit Ihre Steuerelemente sein sollten.

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.