How to constrain varchar in mysql 5.1? - mysql

I need to create column in mysql 5.1 that can store user's feedback.
It shouldn't be too long, so I think not more 1000 characters of UTF-8.
The question is how to represent this efficiently in mysql 5.1.
For now I have:
`description` varchar NOT NULL,
But how to constrain varchar to hold at most 1000 characters of UTF-8?

From the documentation:
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions. The effective maximum length of a VARCHAR in MySQL 5.0.3 and later is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used.
This means that you can store up to 65,535 bytes in a VARCHAR column. However, from the String Type Overview:
MySQL interprets length specifications in character column definitions in character units. (Before MySQL 4.1, column lengths were interpreted in bytes.) This applies to CHAR, VARCHAR, and the TEXT types.
So, declare your table with a UTF8 collation and set the length of the varchar to 1,000 characters and MySQL will do the work for you behind the scenes.

Since the size is apparently defined in bytes, ...
-correction- Field size is defined in 'character units'. It's a bit unclear what they mean by that, but I guess they mean 'code units'.
Removed the rest of the detailed explanation, since it wasn't (entirely true).
Correction. In MySQL you actually define the number of characters in the field. It is still limited to the 65535 byte boundary though. Above that, MySQL just reserves 3 bytes per character for UTF-8, which means that you cannot have UTF-8 fields of more than 21844 characters, and declaring a field als VARCHAR(21900) will just fail for that reason: " Column length too big for column 'field1' (max = 21845); use BLOB or TEXT instead: ". The number in this message is wrong, by the way. The actual maximum size is 21844. 21845 is 1/3 of 65535, but I guess you need to subtract the two bytes for the field size header as well.
The limit of 3 bytes is weird, though. The unicode definition is designed to be able to expand with extra characters. There are already supplementary characters of 4 bytes, that actually cannot be stored in a UTF-8 varchar(1) field, or any varchar field for that matter, since MySQL just doesn't seem able to read those characters: "Incorrect string value: '\xF0\xA0\x9C\x8E' for column 'field1' at row 1". So I guess you would need an actual binary/blob column to be able to store these characters.
I think the documentation about this subject is pretty poor, but I've tried some things and came to this conclusion. You can see the fiddle here: http://sqlfiddle.com/#!2/4d938
To the question:
So for your specific situation, declaring the field as varchar(1000) will do the trick, presuming you don't want people to use the supplementary characters in their feedback.
Some things to consider though:
I think a 'feedback' field of 1000 characters is pretty small. For many folks this will be enough, but if you have to say more, it is annoying if you can't. So I would make the field bigger.
varchar fields are stored in the record and consume a part of the maximum row size of 65536 bytes. This is an important fact. You cannot have two varchar(20000) fields in a row, because together they would be larger than this maximum row size.
A better alternative for large text fields would be therefor be to make them TEXT or MEDIUMTEXT, which can be even larger and are stored in a different way.

Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions.
http://dev.mysql.com/doc/refman/5.0/en/char.html

Related

Mysql memory efficiency and type declaration

I have heard that in MsSQL/Access databases that if you declare a varchar of length 100, it declares those 100 chars every row, even if there is only one char in that column.
I have two questions about this.
First: is this true? And if yes, does this also work like this in MySQL?
Why i'm asking this:
I'm working a lot with mysql, and i came across a table database with 128 longtext-columns. The reasoning behind this was "We cannot be certain how much data gets stored in these columns. sometimes it's 1 char, sometimes thousands." I was wondering if this was the right way storage-wise, or that he has to do some changes.
No, VARCHAR is meant for variable length text, while CHAR is fixed length. The number parameter is the character limit for the text but VARCHAR only uses up as much space as the actual characters you enter in that row (+ some bytes to store the length used).
MySQL, Microsoft SQL Server and pretty much all relational databases work the same way with VARCHAR. Every column takes up some minimum amount of space in a row but with VARCHAR it would be the bytes to store the text + bytes to store the length of the text. No text entered would mean just a 1 or 2 bytes used to save '0' as the length.
If you don't know how much text data will be entered, then use LONGTEXT in MySQL or NVARCHAR(MAX) in MS-SQL. This datatype allows you to store an unlimited amount of text efficiently (up to the row size limitations of the database itself). It's just a bigger, unlimited length version of standard VARCAHR.
For SQL Server the answer is no. From the documentation on MSDN:
varchar [ ( n | max ) ]
Variable-length, non-Unicode string data. n
defines the string length and can be a value from 1 through 8,000. max
indicates that the maximum storage size is 2^31-1 bytes (2 GB). The
storage size is the actual length of the data entered + 2 bytes. The
ISO synonyms for varchar are char varying or character varying.
It is possible someone was confusing VARCHAR and CHAR. The CHAR data type requires a fixed amount of storage, based on the maximum allowed size.
EDIT
Rereading your question I'm not entirely sure I've followed your meaning. If you were not referring to the required storage space then please disregard.

How does MySQL varchar know how many bytes indicate the length?

The MySQL manual and several StackOverflow answers make it clear that varchar uses:
1 byte for varchars with 0-255 characters in them
2 bytes for varchars with more than 255 characters in them.
The first part makes sense. A single byte can store 256 different values, i.e. 0 through 255.
What I am trying to figure out is how MySQL knows how many bytes indicate the length.
Imagine a 255-char varchar starting with the following bytes: [255][w][o][r][d]~
According to the manual, only the first byte is used to indicate the length in this scenario. When reading the field, MySQL will somehow have to know that this is the case here, and that the second byte is not part of the length.
Now imagine a 256-char varchar starting with the following bytes: [255][1][w][o][r][d]~
Now MySQL miraculously knows that it should interpret the first two bytes as the length, when reading the field.
How does it distinguish? The only foolproof way I have come up with is to interpret only the first byte as length, then determine if the text length matches (in its current encoding), and if not, we know that the first two bytes must be the length.
It happens at the time of definition. All length prefixes will be the same size in bytes for a particular VARCHAR column. The VARCHAR column will use 2 bytes or the VARCHAR column will use 1 byte, depending on the defined size in characters, and the character set.
All VARCHAR columns defined such that it might require more than 255 bytes use 2 bytes to store the size. MySQL isn't going to use 1 byte for some values in a column and 2 bytes for others.
MySQL documentation on CHAR and VARCHAR Types states this pretty clearly (emphasis mine):
A column uses one length byte if values require no more than 255
bytes, two length bytes if values may require more than 255 bytes.
If you declare a VARCHAR(255) column to use the utf8 character set, it's still going to use 2 bytes for the length prefix, not 1, since the length in bytes may be greater than 255 with utf8 characters.

Is it wise to declare a VARCHAR with a value greater than 255 in MySQL?

I just noticed in the documentation that in versions greater than 5.0.3 of MySQL you can declare varchar's with larger values than 255. In the past I've switched datatypes for anything larger than 255 but I'm wondering if it's better practice now to define larger string values using varchar(1000) or whatever length is appropriate.
Is this common with other databases now as well, or is it best to stick with 255 as the max value and change datatypes above that?
As the answer #Eric pointed out suggests, VARCHARs are stored in table while TEXTs are stored in a separate file - the only truly important point that you have to keep in mind when designing a table structure is the row size limitation (MySQL limits each row / record to 65 KB).
I suggest you use VARCHARs for "one-liners" - anything that has a text input as its data source.
In my opinion, I would discourage to approach. When you need more than 255 characters, use TEXT are some more suitable.
Update: VARCHAR is now limited to 65535 bytes, but a row in MySQL cannot contain more than 65535 bytes.
You have to know that VARCHAR and fields like that are stored directly into your database when TEXT for example will be stored outisde the row why a pointer inside the row linking to it.
So if you want to use big VARCHAR, make sure they will not be too big and won't interfere with the rest of the data in the row.
For example, having mutltiple VARCHAR fields that can contains up to 65K char would be a bad idea.
The VARCHAR column is limited to 65,535 bytes, which doesn't always mean 65,535 characters depending on which character set you are using.
If your using the latin1 character set which is one byte per character you won't run into any issues because the length of the string in the same as the amount of storage needed.
If you use a character set that stores multi-byte characters you can only set the length to be what the character set will allow. For instance the utf8 character set can have a maximum length of 21,844 characters.

Confusion about varchar datatype

My server has my SQL version of 5.0.91-community, now i have to store a long string of approx about 500 character more or less, i thought of going with text data type but then someone told me it slows the performance, i wanted to know more about varchar and it's limit.
i used to think that varchar is only limited to 255 characters, but then i read it somewhere it is capable of storing more then that in the newer version i.e >= 5.0.3 , as i am using 5.0.91 what do you think i should use? if i use it like varchar(1000) is it still valid?
thank you.
The documentation is here,
varchar has a max size of 65,535 in MySQL 5.0.3 and later , before 5.0.3 the limit was 255
Note that the effective size is less,
The effective maximum length of a
VARCHAR in MySQL 5.0.3 and later is
subject to the maximum row size
(65,535 bytes, which is shared among
all columns) and the character set
used.
You have to specify the max size, e.g. varchar(1000). Just stating varchar isn't enough.
From The CHAR and VARCHAR Types
Values in VARCHAR columns are
variable-length strings. The length
can be specified as a value from 0 to
65,535. The effective maximum length
of a VARCHAR is subject to the maximum
row size (65,535 bytes, which is
shared among all columns) and the
character set used.
According to the MySQL doc:
TEXT differs from VARCHAR in the following ways:
There is no trailing-space removal for TEXT columns when values are stored or retrieved. Before MySQL 5.0.3, this differs from VARCHAR, for which trailing spaces are removed when values are stored.
For indexes on TEXT columns, you must specify an index prefix length. For CHAR and VARCHAR, a prefix length is optional.
TEXT columns cannot have DEFAULT values.
Apart from these differences, using VARCHAR like using TEXT, so the question of size is not what should make you choose between those two, unless you really need to store no more characters than 1000.
In MySQL, VARCHAR accepts maximum of 65535 chars.
You can assure yourself very easy. Mysql documentation is openly accessed and it says
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions
as for the performance issues, it doesn't matter. Not data type but data relations affect performance.

MySQL VARCHAR size limit

If I have a column in table with field of type VARCHAR(15) and if I try to insert data of length 16, MySQL gives an error stating
Data too long for column 'testname' at row 1
Does anyone know why VARCHAR fields in MySQL take fixed length? Also how many bytes does a VARCHAR field take per record based on the size given?
From the MySQL 5.0 Manual:
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions. The effective maximum length of a VARCHAR in MySQL 5.0.3 and later is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used.
I only use VARCHAR when I'm certain that the data the column needs to hold will never exceed a certain length, and even then I'm cautious. If I'm storing a text string I tend to use one of the TEXT types.
Check out the MySQL Storage Requirements for more information on how the bytes are used.
If you set a column to be varchar(15) the maximum bytes allowed is 15. Thus you can't pass it more than 15 characters without modifying the column to support more than 15. If you store a 4 character string it should only use around 4 bytes out of a possible 15, whereas if you used char(15) it would have filled in the other 11 with empty bytes.
http://dev.mysql.com/doc/refman/5.0/en/char.html
( My byte calculation was probably off since it's always -1/+1 or something like that ).
Small extra local note. The number of bytes used will depend on the encoding scheme in use. 1 byte per character in latin1 encoding, but up to 3 in UTF8. See link in mlambie's answer for details.
If you look here it should tell you everything about varchar you want to know:
http://dev.mysql.com/doc/refman/5.0/en/char.html
Basically, depending on the length you chose it will use 1 or two bytes to track the length of the current string in that column, so it will store the number of bytes for the data you put in, plus one or two bytes.
So, if you put in 'abc' then it will be 4 or 5 bytes used for that column in that row.
If you used char(15) then even 'abc' would take up 15 bytes, as the data is the right-padded to use up the full 15 bytes.