2011-02-02 1 views
5

al momento stiamo impostando le nostre colonne di stringhe su nvarchar(max) anziché specificare una lunghezza specifica per evitare problemi in cui non ci potrebbe essere spazio sufficiente nel database per memorizzare la stringa. Mi sto solo chiedendo se questa è una buona cosa o potrebbe causare problemi dal momento che era ok per fare quindi perché specificare una lunghezza come nvarchar(10) anziché nvarchar(max). Usiamo anche varbinary(max) molto perché non sappiamo quanti dati binari avremo bisogno quindi non sono sicuro di quanto questo sia un effetto o diamo che i nostri inserti non sono veloci come penso che dovrebbero essere. Questo è un esempio di tabella:SqlServer e nvarchar (max)

CREATE TABLE [dbo].[SAMPLETABLE] ( 
[ID] [uniqueidentifier] NOT NULL, 
[FIELD1] [int] NOT NULL, 
[FIELD2] [nvarchar] (2000) NULL, 
[FIELD3] [nvarchar] (max) NULL, 
[FIELD4] [uniqueidentifier] NULL, 
[FIELD5] [int] NULL, 
[FIELD6] [nvarchar] (2000) NULL, 
[FIELD7] [varbinary] (max) NULL, 
[FIELD8] [varbinary] (max) NULL, 
[FIELD9] [varbinary] (max) NULL, 
[FIELD10] [uniqueidentifier] NULL, 
[FIELD11] [nvarchar] (2000) NULL, 
[FIELD12] [varbinary] (max) NULL, 
[FIELD13] [varbinary] (max) NULL, 
[FIELD14] [bit] NULL, 
[FIELD15] [uniqueidentifier] NULL, 
[FIELD16] [varbinary] (max) NULL, 
[FIELD17] [bit] NULL, 
[FIELD18] [tinyint] NULL, 
[FIELD19] [datetime] NULL, 
[FIELD20] [nvarchar] (2000) NULL, 
PRIMARY KEY CLUSTERED 
( 
    [ID] ASC 
) 
) ON [PRIMARY] 

GO 

Dato un design del tavolo del genere e cambiare il nvarchar(2000) a nvarchar(max) vorrei che le cose peggio (o meglio)? Sqlserver disapprova disegni come questo?

+0

Che tipo di dati stai memorizzando? L'unico * problema * sarà indicizzazione, ricerca e vincoli. Ciò non rende comunque il cambiamento una buona idea. – Matthew

+7

** per favore non farlo! ** Se fossi stato assunto in un posto che ha tutti i loro tavoli come questo, correrei urlando fuori dalla porta! Quindi aggiungi il PK uniqueidentifier cluster sopra a tutte le colonne nvarchar (max), yuck. Stai uccidendo la tua capacità di indicizzare i tuoi dati. Un giorno presto, tornerai a fare una domanda sul perché la tua query è così lenta e non ci sarà molto da fare per velocizzarla. Nel corso della giornata, tutte le lingue principali/popolari sono state digitate fortemente, ma non così tanto ora. Vi imbatterete in problemi se provate ad usare "quella" stampella in un database. –

+0

@ KM Se avessi potuto, avrei alterato il tuo commento un milione di volte, si tratta di un orribile design di database. – HLGEM

risposta

11

Se sei felice per J. Random Developer, sei mesi dopo, inserire un'opera di Shakespeare in ogni colonna, quindi bene.

Per me, gran parte della modellazione dei dati sta seriamente pensando a quali dati desidero consentire in ogni colonna e quali dati desidero proibire. Applico quindi i vincoli CHECK appropriati per ottenere tali restrizioni (come consente il migliore SQL Server). Avere un controllo ragionevole della lunghezza disponibile "gratuitamente" è sempre sembrato un bonus.


sei anche non sta facendo molto "prova di futuro" - cambiando la lunghezza di una (n) della colonna varchar ad un valore più grande in un secondo momento è, credo, una pura operazione di meta-dati. Quindi direi dimensionare le colonne in modo appropriato per i dati che ci si aspetta di trattare oggi (e ok, per il prossimo anno o giù di lì). Se è necessario espanderli in un secondo momento, sono necessari secondi.

+0

Eccellente poitns. Permettere qualsiasi lunghezza per una colonna è un'idea così scarsa. Avrai problemi di integrità dei dati per cose che dovrebbero essere di una lunghezza particolare. Quindi inserire la colonna del numero di telefono non fallirà se la persona tenta di inserire una nota di 100 caratteri anche se nessun numero di telefono è mai così lungo. E avanti e avanti. Inoltre nvarchar (max) non può essere indicizzato e quindi causare problemi di prestazioni se è necessario effettuare una ricerca. – HLGEM

+4

@HLGEM, ma il mio numero di telefono è più lungo del normale, è: '1 '; utenti di drop table, ordini di drop table, account di drop table; -' –

+0

@KM, si ottiene il mio punto molto bene. – HLGEM

3

La risposta è la stessa della risposta a "Perché è necessario specificare un numero quando posso memorizzare tutti i numeri come stringhe?" - perché aiuta:

  • efficienza della velocità.
  • efficienza di stoccaggio.
  • l'intenzione dell'autore/architetto.
  • riduce l'errore di dati, poiché si adatta solo un determinato tipo di dati.

Ma non causerà immediatamente alcun "problema" evidente perché nvarchar (10) è un sottoinsieme di nvarchar (max).

+0

+1: questa dovrebbe essere la risposta accettata. –

5

Speriamo non utilizzare la colonna per la ricerca o avere valori univoci ...

indici non possono essere largo più di 900 byte Così si può probabilmente mai creare un indice. Questo è un lato negativo: perché dà

  • davvero brutta prestazione ricerca
  • vincoli unici

Può essere lavorato in giro con una colonna calcolata, ma allora perché non memorizzare ciò che si bisogno?

4

Passare dai tipi di righe ai tipi BLOB è sempre una grande decisione.Devi interiorizzare che i tipi BLOB (VARCHAR(MAX), NVARCHAR(MAX) e VARBINARY(MAX)) sono un tipo completamente diverso internamente dai tipi in fila:

Quindi il passaggio tutte le colonne per i tipi BLOB potrebbe portare in un sacco di effetti collaterali che non hanno considerato: impossibilità di indicizzare le colonne BLOB, la mancanza delle operazioni online, degrado delle prestazioni generali dovuto al codice più lento inerente BLOB ecc. ecc. l'ostacolo più serio potrebbe essere il fatto che non sarà possibile indicizzare le colonne dopo averle rese BLOB. Se questo non è uno stopper, dovrai testare e misurare l'impatto sulle prestazioni.

Le preoccupazioni di modellazione dati di altri hanno sollevate sono in generale valide, ma capisco che spesso nel mondo reale la teoria funziona solo in teoria ...

+0

Grazie per il consiglio "ONLINE". A volte è fondamentale aggiungere l'indice con l'opzione ONLINE. È necessario indicare in questo momento che questa limitazione si applica solo a "Database SQL precedente a V12 e SQL Server precedente a SQL Server 2012" in base al collegamento. –

0

qui è la stessa risposta che ho dato ad un altro ragazzo che voleva tavoli infinite:

Database alternative to MySQL made for millions of TABLES

quella punta sopra è un disegno non ottimale per qualsiasi memorizzazione dati relazionali. Pop fa la donnola per i dati: scegli quello che potresti ottenere dai dati che desideri.

Forse una soluzione SQL non funzionerebbe meglio in modo da poter disporre di dati dinamici e non preoccuparsi dei limiti di colonna.

Penso che se dovessimo rispondere alle domande, penso anche che conviene offrirci le migliori/migliori pratiche quando ci sono alternative al cattivo design.

Pensate il ragazzo venire dopo di te, come detto sopra KM

0

nella mia esperienza non molti campi lunghi 2000 caratteri finiscono indicizzato però. Penso che sia molto meglio usare nvarchar (max) di qualche lunghezza arbitraria che potresti dover troncare i dati se non è abbastanza lungo.

Un esempio che ho visto è una tabella di log degli errori in cui i progettisti di tabelle non erano stati preparati per memorizzare lo stack di chiamate in un campo nvarchar (max), quindi avevano memorizzato i primi n-000 caratteri, risultando in stack di chiamate troncate con le sezioni più interessanti mancanti.