tags:

views:

5342

answers:

16

In SQL Server 2005, are there any disadvantages to making all character fields nvarchar(MAX) rather than specifying a length explicitly, e.g. nvarchar(255)? (Apart from the obvious one that you aren't able to limit the field length at the database level)

+3  A: 

The only problem I found was that we develop our applications on SQL Server 2005, and in one instance, we have to support SQL Server 2000. I just learned, the hard way that SQL Server 2000 doesn't like the MAX option for varchar or nvarchar.

mattruma
+8  A: 

Its a fair question and he did state apart from the obvious...

Disadvantages could include:

Performance implications Query optimizer uses field size to determine most efficent exectution plan

"1. The space alloction in extends and pages of the database are flexible. Thus when adding information to the field using update, your database would have to create a pointer if the new data is longer than the previous inserted. This the database files would become fragmented = lower performance in almost everything, from index to delete, update and inserts. " http://www.sqljunkies.com/WebLog/simons/archive/2006/02/28/Why_use_anything_but_varchar_max.aspx

Integration implications - hard for other systems to know how to integrate with your database Unpredictable growth of data Possible security issues e.g. you could crash a system by taking up all disk space

There is good article here: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html

alexmac
+17  A: 

Same question was asked on MSDN Forums:

From the original post (much more information there):

When you store data to a VARCHAR(N) column, the values are physically stored in the same way. But when you store it to a VARCHAR(MAX) column, behind the screen the data is handled as a TEXT value. So there is some additional processing needed when dealing with a VARCHAR(MAX) value. (only if the size exceeds 8000)

VARCHAR(MAX) or NVARCHAR(MAX) is considered as a 'large value type'. Large value types are usually stored 'out of row'. It means that the data row will have a pointer to another location where the 'large value' is stored...

David Kreps
So should the question be, is there a difference between using N/VARCHAR(MAX) and N/TEXT?
Unsliced
If I recall correctly, aren't they only stored out of row if the size exceeds 8k?
Sam Schutte
It's a bargain between space and performance. VARCHAR(MAX) with the use of pointers consumes space wisely, while does additional processing for that intelligence. I think, the decision pretty much depends on the cost difference between storage and processing power.
pencilslate
I read the answer as "no, there is no disadvantage to using `N/VARCHAR(MAX)`" because there is additional processing "only if the size exceeds 8000". Thus, you incur the cost **only when necessary**, and your database is **less restrictive**. Am I reading this wrong? Seems like you would almost always want `N/VARCHAR(MAX)` rather than `N/VARCHAR(1-8000)`...
Kent Boogaart
Dead link above - the working link for the question on MSDN is*http://social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/4d9c6504-496e-45ba-a7a3-ed5bed731fcc*
Jagd
+1  A: 

I had a udf which padded strings and put the output to varchar(max). If this was used directly instead of casting back to the appropriate size for the column being adjusted, the performance was very poor. I ended up putting the udf to an arbitrary length with a big note instead of relying on all the callers of the udf to re-cast the string to a smaller size.

Cade Roux
+1  A: 

This will cause a performance problem, although it may never cause any actual issues if your database is small. Each record will take up more space on the hard drive and the database will need to read more sectors of the disk if you're searching through a lot of records at once. For example, a small record could fit 50 to a sector and a large record could fit 5. You'd need to read 10 times as much data from the disk using the large record.

Dan Goldstein
A: 

It will make screen design harder as you will no longer be able to predict how wide your controls should be.

pappes
A: 

Interesting link: Why use a VARCHAR when you can use TEXT?

It's about PostgreSQL and MySQL, so the performance analysis is different, but the logic for "explicitness" still holds: Why force yourself to always worry about something that's relevant a small percentage of the time? If you saved an email address to a variable, you'd use a 'string' not a 'string limited to 80 chars'.

orip
+2  A: 

I jsut don't understand why you'd want to let someone enter in a name of 8000+ characters.

DForck42
He doesn't, he just doesn't think it's the job of the 'data tier'.
Daniel James
+2  A: 

One problem is that if you are having to work with multiple versions of SQL Server, the MAX will not always work. So if you are working with legacy DB's or any other situation that involves multiple versions, you better be very careful.

TheTXI
I think the unspoken assumption on the part of the OP is that he is dealing entirely with 2005+ instances, and that his apps won't need to work on 2000 (or, ack, lower) versions. I totally agree with you if there is a need to support the older versions, though!
John Rudy
John Rudy: I would imagine that's the case, I just know that I've run into those hurdles myself when I didn't think I was going to.
TheTXI
+12  A: 

Sometimes you want the data type to enforce some sense on the data in it.

Say for example you have a column that really shouldn't be longer than, say, 20 characters. If you define that column as VARCHAR(MAX), some rogue application could insert a long string into it and you'd never know, or have any way of preventing it.

The next time your application uses that string, under the assumption that the length of the string is modest and reasonable for the domain it represents, you will experience an unpredictable and confusing result.

Bill Karwin
I agree with this, and some of the other comments, but I still maintain that this is the responsibility of the business tier. By the time it reaches the database tier, it should snap a salute and store the value, no matter how ridiculously long it is.I think what's really at play here is that I think about 90% of the time when a developer specifies varchar(255), his intent is not really 255 characters, but some unspecified middling length value. And given the trade off between unreasonably large values in my db and unforeseen exceptions, I'll take the large values.
Chris B. Behrens
Don't specify varchar(255) if you intend the limit to be shorter.
Bill Karwin
If they are specifying VARCHAR(255) to indicate some unknown length then that's their fault for not properly researching what they're designing. The solution is for the developer to do their job, not for the database to allow unreasonable values.
Tom H.
not helpful to the author. he explicitly excluded this question you gave an answer to.
usr
+2  A: 

Bad idea when you know the field will be in a set range- 5 to 10 character for example. I think I'd only use max if I wasn't sure what the length would be. For example a telephone number would never be more than a certain number of characters.

Can you honestly say you are that uncertain about the approximate length requirements for every field in your table?

I do get your point though- there are some fields I'd certainly consider using varchar(max).

Interestingly the MSDN docs sum it up pretty well:

Use varchar when the sizes of the column data entries vary considerably. Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.

There's an interesting discussion on the issue here.

RichardOD
For things like telephone numbers, I would be much more agreeable to using a char field instead of varchar. As long as you are maintaining a standard in your storage and you don't have to worry about phone numbers from different countries, you should never need a variable field for something like a phone number (10 without any formatting) or zip code (5 or 9-10 if you add the last four digits), etc.
TheTXI
I was referring to telephone numbers that can vary in length. Perhaps I should of put this in the answer. Anything that is fixed length I would use a char field.
RichardOD
Or perhaps I should of said in my comment nchar or char. :-)
RichardOD
The number of characters in a telephone number is pretty much a business requirement. If you were required to store the international standard code along with the number, it could be more than 10. Or, some part of the world might have more than 10 digits for a phone number. Imagine the case of IPV4 to IPV6 transition. No one would have argued that we needed more than 12 digits in the good old IPV4 days. It may not hold good if IPV6 becomes prevalent. This is again a business rule change over a period of time. As it's said, change is the only constant thing we can expect :)
pencilslate
+5  A: 

Think of it as just another safety level. You can design your table without foreign key relationships - perfectly valid - and ensure existence of associated entities entirely on the business layer. However, foreign keys are considered good design practice because they add another constraint level in case something messes up on the business layer. Same goes for field size limitation and not using varchar MAX.

Alex
A: 

legacy system support. If you have a system that is using the data and it is expected to be a certain length then the database is a good place to enforce the length. This is not ideal but legacy systems are sometime not ideal. =P

Tony
+1  A: 

If all of the data in a row (for all the columns) would never reasonably take 8000 or fewer characters then the design at the data layer should enforce this.

The database engine is much more efficient keeping everything out of blob storage. The smaller you can restrict a row the better. The more rows you can cram in a page the better. The database just performs better when it has to access fewer pages.

Matt Spradley
+1  A: 

A reason NOT to use max or text fields is that you cannot perform online index rebuilds i.e. REBUILD WITH ONLINE= ON even with SQL Server Enterprise Edition.

Nick Kavadias
This same restriction is in place for the TEXT field type, so you should still use VARCHAR(MAX) instead of TEXT.
Will Shaver
A: 

The job of the database is to store data so that it can be used by the enterprise. Part of making that data useful is ensuring that it is meaningful. Allowing someone to enter an unlimited number of characters for their first name isn't ensuring meaningful data.

Building these constraints into the business layer is a good idea, but that doesn't ensure that the database will remain intact. The only way to guarantee that the data rules are not violated is to enforce them at the lowest level possible in the database.

Tom H.
IMO, the data length limitations are purely based on the business rules, which can change over a period of time, as the application grows. Changing business rules at the business logic is easier than at the db level. So, i think the db should be flexible enough and shouldn't be tied to business rules such as max permitted length of first name, which is very much dependant on the part of the world you where your user lives in.
pencilslate