Ci sono degli svantaggi nell'usare sempre nvarchar (MAX)?


342

In SQL Server 2005 ci sono degli svantaggi nel rendere tutti i campi di caratteri nvarchar (MAX) anziché specificare esplicitamente una lunghezza, ad esempio nvarchar (255)? (A parte quello ovvio che non sei in grado di limitare la lunghezza del campo a livello di database)


1
Non capisco perché vorresti permettere a qualcuno di inserire un nome di oltre 8000 caratteri.
DForck42,

2
La stessa logica può essere applicata ai linguaggi di programmazione. Perché non tornare alla vecchia variante VB6 per tutti i nostri dati? Non credo che avere assegni e saldi in più di un posto sia necessariamente negativo.
Matt Spradley,


10
Il tuo aggiornamento dovrebbe essere la risposta a questa domanda.
Johann,

la risposta alla domanda è stata spostata nella risposta corretta visto che l'autore originale non l'ha fatto. stackoverflow.com/a/35177895/10245 I 7 anni sono abbastanza tempo :-)
Tim Abell

Risposte:


153

La stessa domanda è stata posta sui forum MSDN:

Dal post originale (molte più informazioni lì):

Quando si memorizzano i dati in una colonna VARCHAR (N), i valori vengono archiviati fisicamente allo stesso modo. Ma quando lo memorizzi in una colonna VARCHAR (MAX), dietro lo schermo i dati vengono gestiti come valore TEXT. Quindi è necessaria un'ulteriore elaborazione quando si ha a che fare con un valore VARCHAR (MAX). (solo se la dimensione supera 8000)

VARCHAR (MAX) o NVARCHAR (MAX) è considerato un "tipo di valore elevato". I tipi di valore elevato vengono generalmente archiviati "fuori riga". Significa che la riga di dati avrà un puntatore a un'altra posizione in cui è memorizzato il "valore grande" ...


2
Quindi dovrebbe essere la domanda, c'è una differenza tra l'utilizzo di N / VARCHAR (MAX) e N / TEXT?
Unlicliced

18
Se ricordo bene, non vengono memorizzati solo fuori riga se la dimensione supera 8k?
Sam Schutte,

79
Ho letto la risposta come "no, non ci sono svantaggi nell'uso N/VARCHAR(MAX)" perché c'è un'ulteriore elaborazione "solo se la dimensione supera 8000". Pertanto, si incorre nel costo solo quando necessario e il database è meno restrittivo . Sto leggendo questo male? Sembra che vorresti quasi sempre N/VARCHAR(MAX)piuttosto che N/VARCHAR(1-8000)...
Kent Boogaart,

1
Dead link sopra - il link funzionante per la domanda su MSDN è social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/…
Jagd

68
Sfortunatamente questa risposta ha una serie di problemi. Fa sembrare il limite 8k come un numero magico, non è vero, il valore viene rimosso dalla riga in base a più fattori, tra cui sp_tableoptions: msdn.microsoft.com/en-us/library/ms173530.aspx . I tipi VARCHAR (255) possono anche essere spinti fuori dalla riga, il 'sovraccarico' menzionato può essere esattamente lo stesso per MAX e 255. Confronta i tipi MAX con i tipi TEXT, quando sono distinti come si ottiene (API completamente diverse da manipolare, archiviazione diversa ecc.). Non menziona le differenze effettive: nessun indice, nessuna operazione online sui tipi MAX
Remus Rusanu,

50

È una domanda giusta e lo ha affermato a parte l'ovvio ...

Gli svantaggi potrebbero includere:

Implicazioni sulle prestazioni Lo Strumento per ottimizzare le query utilizza le dimensioni del campo per determinare il piano di esecuzione più efficace

"1. L'allocazione dello spazio negli spazi estesi e nelle pagine del database è flessibile. Pertanto, quando si aggiungono informazioni al campo mediante l'aggiornamento, il database dovrebbe creare un puntatore se i nuovi dati sono più lunghi di quelli precedentemente inseriti. In questo modo i file del database diventare frammentato = prestazioni inferiori in quasi tutto, dall'indice all'eliminazione, dall'aggiornamento e dagli inserimenti. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx

Implicazioni sull'integrazione - difficile per altri sistemi sapere come integrarsi con il database Crescita imprevedibile dei dati Possibili problemi di sicurezza, ad esempio, è possibile che si blocchi un sistema occupando tutto lo spazio su disco

C'è un buon articolo qui: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html


4
+1 Per le implicazioni di integrazione e sicurezza. Queste sono un'angolazione originale da considerare quando la maggior parte delle altre risposte parla di prestazioni. In relazione alle implicazioni sull'integrazione, qualsiasi strumento (come redattori di report o progettisti di moduli) che utilizza metadati per fornire ragionevoli dimensioni di controllo predefinite richiederebbe molto più lavoro da utilizzare se tutte le colonne lo fossero varchar(max).
Disilluso il

L'integrazione tramite database è la cosa più ridicola che io sappia. Se è stata appena importata una volta, è possibile controllare i dati prima tramite la funzione LEN.
Massima

30

Sulla base del link fornito nella risposta accettata sembra che:

  1. 100 caratteri memorizzati in un nvarchar(MAX)campo verranno archiviati in modo diverso da 100 caratteri in un nvarchar(100)campo: i dati verranno archiviati in linea e non si avrà il sovraccarico di leggere e scrivere i dati "fuori riga". Quindi non preoccuparti.

  2. Se la dimensione è maggiore di 4000 i dati verrebbero archiviati automaticamente "fuori riga", che è quello che vorresti. Quindi non preoccuparti neanche lì.

Però...

  1. Non è possibile creare un indice su un nvarchar(MAX) colonna. È possibile utilizzare l'indicizzazione full-text, ma non è possibile creare un indice sulla colonna per migliorare le prestazioni della query. Per me, questo sigilla l'affare ... è un netto svantaggio usare sempre nvarchar (MAX).

Conclusione:

Se si desidera una sorta di "lunghezza di stringa universale" in tutto il database, che può essere indicizzata e che non sprecherà spazio e tempo di accesso, è possibile utilizzare nvarchar(4000).


1
a proposito, questa è stata una modifica aggiunta alla domanda originale che avrebbe dovuto essere pubblicata come risposta
Tim Abell,

1
Grazie, per me questa è la risposta finale. Mi sono chiesto lo stesso - perché non usarlo nvarchar(max)sempre - come stringin C #? - ma il punto 3) (la questione dell'indice) sta dando la risposta.
SQL Police,

1
Aggiunta una modifica. Come una specie di "lunghezza universale della stringa", puoi sempre usarenvarchar(4000)
SQL Police il

@SQLGeorge Vedi questa eccellente risposta di Martin Smith sull'impatto sulla query delle prestazioni di dichiarare colonne più ampie di quanto non lo saranno mai
billinkc

@billinkc Grazie, è un ottimo articolo. OK, quindi le dimensioni influiscono davvero sulle prestazioni. Modificherò di nuovo la risposta.
SQL Police,

28

A volte vuoi che il tipo di dati imponga un certo senso sui dati in esso contenuti.

Supponiamo ad esempio di avere una colonna che in realtà non dovrebbe essere più lunga, per esempio, di 20 caratteri. Se definisci quella colonna come VARCHAR (MAX), alcune applicazioni non autorizzate potrebbero inserire una lunga stringa in essa e non lo sapresti mai, o avresti modo di impedirlo.

La prossima volta che l'applicazione utilizzerà quella stringa, supponendo che la lunghezza della stringa sia modesta e ragionevole per il dominio che rappresenta, si verificherà un risultato imprevedibile e confuso.


9
Sono d'accordo con questo e alcuni degli altri commenti, ma continuo a sostenere che questa è la responsabilità del livello aziendale. Quando raggiunge il livello del database, dovrebbe scattare un saluto e memorizzare il valore, non importa quanto sia ridicolmente lungo. Penso che ciò che è realmente in gioco qui sia che penso al 90% delle volte in cui uno sviluppatore specifica varchar (255), il suo intento non è davvero 255 caratteri, ma un valore di lunghezza medio non specificato. E dato il compromesso tra valori irragionevolmente grandi nel mio db e eccezioni impreviste, prenderò i valori grandi.
Chris B. Behrens,

4
Se stanno specificando VARCHAR (255) per indicare una lunghezza sconosciuta, allora è colpa loro se non ricercano correttamente ciò che stanno progettando. La soluzione è che lo sviluppatore faccia il proprio lavoro, non che il database consenta valori irragionevoli.
Tom H,

10
non utile per l'autore. ha escluso esplicitamente questa domanda a cui hai dato una risposta.
usr

6
@ Chris B Behrens: non sono d'accordo; lo schema del database fa parte della logica aziendale. La scelta di tabelle, relazioni, campi e tipi di dati è tutta una logica aziendale e vale la pena usare RDBMS per applicare le regole di questa logica aziendale. Per un motivo, è molto raro che vi sia un solo livello di applicazione che accede al database; ad esempio, potresti avere strumenti di importazione ed estrazione dei dati che aggirano il livello aziendale principale, il che significa che hai davvero bisogno del DB per far rispettare le regole.
Vince Bowdren,

1
Se non hai bisogno o vuoi davvero che vengano memorizzate stringhe lunghe, allora è meglio applicare un senso ai dati. Ad esempio, se si memorizza un campo PostCode, si lascerebbe che qualcuno inserisse centinaia o migliaia di caratteri quando dovrebbe essere un massimo di 10 dire. La dimensione massima dovrebbe essere convalidata per tutti i livelli, client, livello aziendale E database. Se si utilizza un approccio Model First, ad esempio con C # e Entity Framework, è possibile definire la dimensione massima nel modello e applicarla al database, alla logica aziendale e alla convalida del client (con elementi simili alla convalida jquery). Usa nvarchar (max) solo se è veramente richiesto
Peter Kerr,

21

Ho controllato alcuni articoli e ho trovato utili script di test da questo: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Quindi l'ho modificato per confrontarlo tra NVARCHAR (10) vs NVARCHAR (4000) vs NVARCHAR (MAX ) e non trovo la differenza di velocità quando si utilizzano numeri specifici ma quando si utilizza MAX. Puoi testare da solo. Spero che questo aiuto.

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
Interessante. Sulla mia scatola sembra che quello MAX sia 4x più lento.
Stucampbell,

4
Nuovi risultati su SQL Server 2012: 10 è due volte più lento di 4k e MAX è 5,5 volte più lento di 4k.
Cassandrad,

1
La maggior parte delle volte è il cast implicito da varchar a nvarchar (max). Prova questo: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (max) = N'ABC ', \ @StartTime DATETIME; SELECT @startTime = GETDATE (); SELEZIONA TOP 1000000 \ @SomeString = \ @abc FROM master.sys.all_columns ac1, master.sys.all_columns ac2; SELECT testTime = 'MAX', Duration = DATEDIFF (ms, \ @ StartTime, GETDATE ()); Ho dovuto inserire le variabili \ before per farlo pubblicare.
Kvasi,

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

2
Grazie per aver aggiunto alcuni numeri reali a questa discussione. Spesso dimentichiamo che la creazione di un test case è il modo più rapido per approfondire.
David C,

13

Pensalo come un altro livello di sicurezza. È possibile progettare la tabella senza relazioni con chiavi esterne - perfettamente valida - e garantire l'esistenza di entità associate interamente a livello aziendale. Tuttavia, le chiavi esterne sono considerate buone prassi di progettazione perché aggiungono un altro livello di vincolo nel caso in cui qualcosa si incasini sul livello aziendale. Lo stesso vale per la limitazione delle dimensioni del campo e per non utilizzare varchar MAX.


8

Un motivo per NON utilizzare i campi max o text è che non è possibile eseguire ricostruzioni di indici online, ad esempio REVISIONE CON ONLINE = ON anche con SQL Server Enterprise Edition.


1
Questa stessa restrizione è valida per il tipo di campo TEXT, quindi dovresti comunque usare VARCHAR (MAX) invece di TEXT.
Will Shaver,

non siamo riusciti a ricostruire il nostro indice cluster a causa di ciò. ci è costato molto spazio su disco fino a quando non abbiamo potuto estrarre la colonna nella sua tabella (non potevamo permetterci di bloccare la tabella per più di 7 secondi)
Choco Smith

4

L'unico problema che ho riscontrato è stato che sviluppiamo le nostre applicazioni su SQL Server 2005 e, in un'istanza, dobbiamo supportare SQL Server 2000. Ho appena imparato, nel modo più duro che a SQL Server 2000 non piace l'opzione MAX per varchar o nvarchar.


2
Quindi perché non sviluppare solo il minimo comune denominatore?
binki,

4

Una cattiva idea quando sai che il campo sarà compreso tra 5 e 10 caratteri, ad esempio. Penso che userei max solo se non fossi sicuro di quale lunghezza sarebbe. Ad esempio un numero di telefono non sarebbe mai superiore a un certo numero di caratteri.

Puoi onestamente dire che non sei così sicuro dei requisiti di lunghezza approssimativa per ogni campo della tua tabella?

Capisco però: ci sono alcuni campi che sicuramente prenderei in considerazione usando varchar (max).

È interessante notare che i documenti MSDN lo riassumono abbastanza bene:

Utilizzare varchar quando le dimensioni delle voci di dati della colonna variano considerevolmente. Utilizzare varchar (max) quando le dimensioni delle voci di dati della colonna variano considerevolmente e la dimensione potrebbe superare gli 8.000 byte.

C'è un'interessante discussione sull'argomento qui .


2
Per cose come i numeri di telefono, sarei molto più gradito all'utilizzo di un campo char anziché di varchar. Finché mantieni uno standard nella tua memoria e non devi preoccuparti dei numeri di telefono di diversi paesi, non dovresti mai aver bisogno di un campo variabile per qualcosa come un numero di telefono (10 senza alcuna formattazione) o un codice postale (5 o 9-10 se aggiungi le ultime quattro cifre), ecc.
TheTXI

Mi riferivo a numeri di telefono che possono variare in lunghezza. Forse dovrei metterlo nella risposta. Qualunque cosa che abbia una lunghezza fissa userei un campo char.
RichardOD,

O forse avrei dovuto dire nel mio commento nchar o char. :-)
RichardOD,

2
Il numero di caratteri in un numero di telefono è praticamente un requisito aziendale. Se ti fosse richiesto di memorizzare il codice standard internazionale insieme al numero, potrebbe essere più di 10. Oppure, alcune parti del mondo potrebbero avere più di 10 cifre per un numero di telefono. Immagina il caso della transizione da IPV4 a IPV6. Nessuno avrebbe sostenuto che avessimo bisogno di più di 12 cifre nei bei vecchi tempi di IPV4. Potrebbe non andare bene se IPV6 diventa prevalente. Questa è di nuovo una modifica delle regole aziendali per un periodo di tempo. Come si dice, il cambiamento è l'unica cosa costante che possiamo aspettarci :)
pencilslate

2
Fai attenzione a supporre di sapere quanti caratteri possono essere nel campo di un numero di telefono o che tipo di caratteri saranno. A meno che il sistema non utilizzi tali dati per comporre il numero (nel qual caso è necessario essere severi sui formati), l'utente potrebbe legittimamente inserire lì stringhe inaspettatamente lunghe, ad es. "0123 456 78910 chiedere alla reception l'estensione 45 e quindi trasferire a James".
Vince Bowdren,

4

Il compito del database è archiviare i dati in modo che possano essere utilizzati dall'azienda. Parte del rendere tali dati utili è garantire che siano significativi. Consentire a qualcuno di inserire un numero illimitato di caratteri per il proprio nome non garantisce dati significativi.

La creazione di questi vincoli nel livello aziendale è una buona idea, ma ciò non garantisce che il database rimanga intatto. L'unico modo per garantire che le regole sui dati non vengano violate è applicarle al livello più basso possibile nel database.


6
IMO, i limiti di lunghezza dei dati si basano esclusivamente sulle regole aziendali, che possono cambiare in un determinato periodo di tempo man mano che l'applicazione cresce. La modifica delle regole aziendali a livello di logica aziendale è più semplice che a livello di db. Quindi, penso che il db dovrebbe essere abbastanza flessibile e non dovrebbe essere legato a regole aziendali come la lunghezza massima consentita del nome, che dipende molto dalla parte del mondo in cui vive l'utente.
pencilslate

3

Un problema è che se devi lavorare con più versioni di SQL Server, il MAX non funzionerà sempre. Quindi, se stai lavorando con DB legacy o qualsiasi altra situazione che coinvolge più versioni, è meglio stare molto attenti.


Penso che l'ipotesi non espressa da parte dell'OP sia che si occupi interamente delle istanze 2005+ e che le sue app non dovranno funzionare su versioni 2000 (o, ack, inferiori). Sono assolutamente d'accordo con te se è necessario supportare le versioni precedenti!
John Rudy,

John Rudy: Immagino che sia così, so solo che mi sono imbattuto in quegli ostacoli da solo quando non pensavo che stavo per farlo.
TheXI

In realtà questo è ancora un problema prevalente con cose moderne a causa di SQL CE 4 che non supporta i tipi di colonna MAX, quindi l'interoperabilità è una seccatura.
Giovanni

3

Come sottolineato sopra, si tratta principalmente di un compromesso tra archiviazione e prestazioni. Almeno nella maggior parte dei casi.

Tuttavia, c'è almeno un altro fattore che dovrebbe essere considerato quando si sceglie n / varchar (Max) su n / varchar (n). I dati verranno indicizzati (come, per esempio, un cognome)? Poiché la definizione MAX è considerata un LOB, tutto ciò che è definito MAX non è disponibile per l'indicizzazione. e senza un indice, qualsiasi ricerca che coinvolga i dati come predicato in una clausola WHERE verrà forzata in una scansione della tabella completa, che è la peggiore prestazione che puoi ottenere per le ricerche di dati.


2

1) Il server SQL dovrà utilizzare più risorse (memoria allocata e tempo della CPU) quando ha a che fare con nvarchar (max) vs nvarchar (n) dove n è un numero specifico per il campo.

2) Cosa significa questo per quanto riguarda le prestazioni?

Su SQL Server 2005, ho eseguito una query su 13.000 righe di dati da una tabella con 15 colonne nvarchar (max). Ho cronometrato ripetutamente le query e poi ho cambiato le colonne in nvarchar (255) o meno.

Le query precedenti all'ottimizzazione sono state in media di 2,0858 secondi. Le query dopo la modifica sono state restituite in media 1,90 secondi. Sono stati circa 184 millisecondi di miglioramento rispetto alla query select * di base. Questo è un miglioramento dell'8,8%.

3) I miei risultati sono in concomitanza con alcuni altri articoli che indicavano una differenza di prestazioni. A seconda del database e della query, la percentuale di miglioramento può variare. Se non hai molti utenti simultanei o molti record, la differenza di prestazioni non sarà un problema per te. Tuttavia, la differenza di prestazioni aumenterà all'aumentare del numero di record e degli utenti simultanei.


1

Ho avuto un udf che ha riempito le stringhe e messo l'output su varchar (max). Se questo è stato usato direttamente invece di tornare alle dimensioni appropriate per la colonna da regolare, le prestazioni erano molto scarse. Ho finito per mettere udf ad una lunghezza arbitraria con una grande nota invece di fare affidamento su tutti i chiamanti di udf per ripetere il cast della stringa su una dimensione più piccola.


1

supporto del sistema legacy. Se si dispone di un sistema che utilizza i dati e si prevede che abbia una certa lunghezza, il database è un buon posto per imporre la lunghezza. Questo non è l'ideale ma i sistemi legacy a volte non sono l'ideale. = P


1

Se tutti i dati in una riga (per tutte le colonne) non prenderebbero mai ragionevolmente 8000 o meno caratteri, il design a livello di dati dovrebbe imporlo.

Il motore di database è molto più efficiente mantenendo tutto fuori dall'archiviazione BLOB. Più piccolo è possibile limitare una riga, meglio è. Più righe puoi stipare in una pagina, meglio è. Il database funziona meglio quando deve accedere a un minor numero di pagine.


1

I miei test hanno dimostrato che ci sono differenze nella selezione.

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

Link interessante: Perché usare un VARCHAR quando puoi usare TEXT?

Riguarda PostgreSQL e MySQL, quindi l'analisi delle prestazioni è diversa, ma la logica di "explicitness" è ancora valida: perché forzarti a preoccuparti sempre di qualcosa che è rilevante una piccola percentuale delle volte? Se salvassi un indirizzo email in una variabile, utilizzeresti una "stringa" e non una "stringa limitata a 80 caratteri".


1
È simile a sostenere che non si dovrebbero avere vincoli di controllo per assicurarsi che l'età di una persona non sia un numero negativo.
Jonathan Allen,

Vedo una differenza tra correttezza dei dati e ottimizzazione delle prestazioni.
Orip,

0

Lo svantaggio principale che posso vedere è che diciamo che hai questo:

Quale ti dà il maggior numero di informazioni sui dati necessari per l'interfaccia utente?

Questo

            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]

O questo?

            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
Preferirei la logica aziendale che mi dica che un nome di società può contenere un massimo di 50 caratteri anziché basarsi su una tabella di database per tali informazioni.
Khan,

Sono d'accordo con Jeff. Non credo che il negozio di persistenza sia il posto giusto per definire le tue regole di business. E in un'architettura a strati la tua interfaccia utente non sarebbe nemmeno a conoscenza del livello di persistenza.
Stucampbell,

A meno che, ovviamente, non si stia utilizzando un valore limitato a una dimensione specifica, ad esempio il codice ISO per paese.
Ben

2
Cosa c'entra questo con un def di tabella? Puoi ancora avere la logica aziendale. Penso che il tuo punto non abbia senso in relazione a come è progettato un tavolo. Se vuoi ancora progettare un qualche tipo di definizione nel tuo livello aziendale, così sia. Sebbene ciò che avrebbe più senso, è comunque utilizzare un proc memorizzato nel livello aziendale; non è un tavolo def ??
carlos martini,

1
Sembra impopolare ma concordo con Carlos, se il db imposta una dimensione massima, allora puoi stare comodo in tutti i livelli che costruisci sopra di esso con ciò che probabilmente dovrai affrontare. Ciò è particolarmente importante se hai più sistemi che scrivono nel tuo database.
Tim Abell,

0

Uno svantaggio è che si progetterà attorno a una variabile imprevedibile e probabilmente si ignorerà invece di sfruttare la struttura interna dei dati di SQL Server, costituita progressivamente da Row (s), Page (s) ed Extent (s).

Il che mi fa pensare all'allineamento della struttura dei dati in C e che essere consapevoli dell'allineamento è generalmente considerato una buona cosa (TM). Idea simile, contesto diverso.

Pagina MSDN per pagine ed estensioni

Pagina MSDN per i dati di overflow delle righe


0

in primo luogo ho pensato a questo, ma poi ho pensato di nuovo. Ci sono implicazioni sulle prestazioni, ma allo stesso modo serve come forma di documentazione per avere un'idea delle dimensioni dei campi. E si applica quando quel database si trova in un ecosistema più grande. Secondo me la chiave deve essere permissiva ma solo entro limiti ragionevoli.

ok, ecco i miei sentimenti semplicemente sulla questione del business e della logica del livello dati. Dipende, se il tuo DB è una risorsa condivisa tra sistemi che condividono la logica di business, allora ovviamente sembra un luogo naturale per applicare tale logica, ma non è il modo MIGLIORE per farlo, il modo MIGLIORE è fornire un'API, questo consente l'interazione da testare e mantiene la logica aziendale a cui appartiene, mantiene i sistemi disaccoppiati, mantiene i livelli all'interno di un sistema disaccoppiato. Se tuttavia si suppone che il tuo database stia servendo una sola applicazione, allora lascia che AGILE pensi, che cosa è vero adesso? design per ora. Se e quando è necessario tale accesso, fornire un'API a tali dati.

ovviamente, però, questo è l'ideale, se stai lavorando con un sistema esistente la probabilità è che dovrai farlo diversamente, almeno nel breve periodo.


-1

Ciò causerà un problema di prestazioni, sebbene non possa mai causare problemi reali se il database è piccolo. Ogni record occuperà più spazio sul disco rigido e il database dovrà leggere più settori del disco se si cercano più record contemporaneamente. Ad esempio, un piccolo record potrebbe adattarsi a 50 di un settore e un record di grandi dimensioni potrebbe adattarsi a 5. Dovresti leggere 10 volte più dati dal disco usando il record di grandi dimensioni.


5
-1. Una stringa di lunghezza 100 memorizzata in una nvarchar(max)colonna non occupa più spazio su disco rispetto a una nvarchar(100)colonna.
Martin Smith,

Quello che stai descrivendo è corretto se la dimensione dei dati memorizzati è maggiore, ma questa domanda riguarda se il tipo di dati ha implicazioni sulle prestazioni o altre considerazioni.

-2

Renderà più difficile la progettazione dello schermo poiché non sarai più in grado di prevedere la larghezza dei controlli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.