I always thought that the number in the parenthesis represented the field length?
However, I understand that is not always the case. Maybe it's a MySQL issue? Someone told me if I set a field to 9 characters long, I can add a value that's more than 9 characters but only the first 9 will be saved.
Example:
CREATE TABLE `person` (
id INT,
age INT(2)
);
If that's the case, shouldn't I select something like TINYINT instead of INT for age?
INT(2) will generate an INT with the minimum display width of 2:
MySQL supports an extension for optionally specifying the display width of integer data types in parentheses following the base keyword for the type. For example, INT(4) specifies an INT with a display width of four digits. This optional display width may be used by applications to display integer values having a width less than the width specified for the column by left-padding them with spaces. (That is, this width is present in the metadata returned with result sets. Whether it is used or not is up to the application.)
The display width does not constrain the range of values that can be stored in the column. Nor does it prevent values wider than the column display width from being displayed correctly. For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range permitted by three digits are displayed in full using more than three digits.
this does not affect the range of possible values that can be stored in the field; neither is it the number of bytes used to store it. It seems to be only a recommendation for applications how to show the value, unless ZEROFILL is used (see the linked page).
A unsigned TINYINT (0...255) would probably do as well, unless cryopreservation takes a big step forward during the lifetime of your application.
That's the case for field types like vchar, but for numbers it represents the number of bytes which it uses to represent the number. An integer of two bytes means you can hold a number 2^16 - 1 (8 bits in a byte, so 16 total). If it's age, I figure you ought to be safe with two bytes. ;)
Related
According to the documentation, the attribute in the parentheses (e.g. the "3" in SMALLINT(3)) is supposed to constrain the display of the values of the SMALLINT to three digits. However, when I inserted five test numbers (9, 99, 999, 9999, 99999), it took each number at its full value rather than capping it at the three digits and displayed it accordingly (except for 99999, of course, which it capped at 32767). Shouldn't the numbers be limited, at least while being displayed, to three digits? Or am I missing the true purpose here?
For integer types, the attribute relates to display width and can only be seen if you add zerofill to the column create statement.
Display width does not effect the storage allocated to the column, only the padded display when zerofill is enabled.
See also this explanation: http://matthom.com/archive/2006/11/28/mysql-integer-columns-and-display-width
As stated in the manual:
M indicates the maximum display width for integer types. For floating-point and fixed-point types, M is the total number of digits that can be stored (the precision). For string types, M is the maximum length. The maximum permissible value of M depends on the data type.
Further, as stated here:
MySQL supports an extension for optionally specifying the display width of integer data types in parentheses following the base keyword for the type. For example, INT(4) specifies an INT with a display width of four digits. This optional display width may be used by applications to display integer values having a width less than the width specified for the column by left-padding them with spaces. (That is, this width is present in the metadata returned with result sets. Whether it is used or not is up to the application.)
The display width does not constrain the range of values that can be stored in the column. Nor does it prevent values wider than the column display width from being displayed correctly. For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range permitted by three digits are displayed in full using more than three digits.
When used in conjunction with the optional (nonstandard) attribute ZEROFILL, the default padding of spaces is replaced with zeros. For example, for a column declared as INT(4) ZEROFILL, a value of 5 is retrieved as 0005.
Note
The ZEROFILL attribute is ignored when a column is involved in expressions or UNION queries.
If you store values larger than the display width in an integer column that has the ZEROFILL attribute, you may experience problems when MySQL generates temporary tables for some complicated joins. In these cases, MySQL assumes that the data values fit within the column display width.
All integer types can have an optional (nonstandard) attribute UNSIGNED. Unsigned type can be used to permit only nonnegative numbers in a column or when you need a larger upper numeric range for the column. For example, if an INT column is UNSIGNED, the size of the column's range is the same but its endpoints shift from -2147483648 and 2147483647 up to 0 and 4294967295.
Floating-point and fixed-point types also can be UNSIGNED. As with integer types, this attribute prevents negative values from being stored in the column. Unlike the integer types, the upper range of column values remains the same.
If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column.
Integer or floating-point data types can have the additional attribute AUTO_INCREMENT. When you insert a value of NULL (recommended) or 0 into an indexed AUTO_INCREMENT column, the column is set to the next sequence value. Typically this is value+ 1, where value is the largest value for the column currently in the table. AUTO_INCREMENT sequences begin with 1.
I just created one role table and i defined role_id tinyint(1), even though i was able to store 99, 200 max upto 255 as tinyint limit for unsigned. so then what is the meaning of passing this size in data-types?
when read little that, it is about the display width, but when i fetch result on my php page, it displays as they are stored in the table.
Any mentor, can you please guide me to clear it?
from 10.1.1. Numeric Type Overview:
M indicates the maximum display width for integer types. The maximum legal
display width is 255. Display width is unrelated to the range of values a type
can contain [...].
So tinyint(M), or tinyint(1) in your case, means that any value stored in role_id will be chopped to a length of one byte when being displayed by MySQL. Similarly tinyint(3) would case a one digit integer to be padded with two spaces. You can also use tinyint(3) zerofill to pad with 0s instead, but it has the side-effect of making your tinyints unsigned.
However, regardless how you specify your tinyints they will be stored internally as an integer in the range [-128,127] (signed) or [0,255] (unsigned), and so that's the value PHP will receive when querying your database.
You can use mysql_field_len and substr to limit the display width similarly with PHP.
According to the mySQL Docs a datatype of int (signed) has a range of -2147483648 to 2147483647. When I create a table with phpMyAdmin, and export the table structure it shows the following:
`unit_id` int(11) NOT NULL
Why the (11)? Doesn't int tell mySQL everything it needs to know?
This is the optional 'width' attribute, which can be used by applications to display the value.
To quote the documentation:
MySQL supports an extension for optionally specifying the display
width of integer data types in parentheses following the base keyword
for the type. For example, INT(4) specifies an INT with a display
width of four digits. This optional display width may be used by
applications to display integer values having a width less than the
width specified for the column by left-padding them with spaces. (That
is, this width is present in the metadata returned with result sets.
Whether it is used or not is up to the application.)
The display width does not constrain the range of values that can be
stored in the column. Nor does it prevent values wider than the column
display width from being displayed correctly. For example, a column
specified as SMALLINT(3) has the usual SMALLINT range of -32768 to
32767, and values outside the range permitted by three digits are
displayed in full using more than three digits.
That sets the display width which is returned with the result set. It has no bearing on the storage size.
For years I have been under the assumption when I create a new column of type bigint(12) for a MySQL table that the field is limited to integers with up to 12 digits. However, I recently noticed that values up to 16 digits are able to be written into and selected out of a bigint(12) defined column without any warnings or issues.
Can someone please help me understand why this is the case and what that column definition actually means? Thanks in advance!
bigint(12) is not truncated at all. The 12 is used for display purposes.
Have a look at Numeric Types
Numeric Type Attributes
MySQL supports an extension for
optionally specifying the display
width of integer data types in
parentheses following the base keyword
for the type. For example, INT(4)
specifies an INT with a display width
of four digits. This optional display
width may be used by applications to
display integer values having a width
less than the width specified for the
column by left-padding them with
spaces. (That is, this width is
present in the metadata returned with
result sets. Whether it is used or not
is up to the application.)
The display width does not constrain the range of values that can be stored
in the column. Nor does it prevent
values wider than the column display
width from being displayed correctly.
read Numeric Type Attributes section from MySql documentation INT(4) specifies an INT with a display width of four digits
I have several tables with some pretty standard data in each. Can somebody help me optimize them by telling me the best column types for this data. Whats beside them is what I have currently.
Number (max length 7) --> MEDIUMINT(8) Unsigned
Text (max length 30) --> VARCHAR(30)
Text (max length 200) --> VARCHAR(200)
Email Address (max length 200) --> VARCHAR(200)
Number (max length 4) --> SMALLINT(5) Unsigned
Number (either 0 or 1) --> TINYINT(1) Unsigned
Text (max length 500) --> TEXT
Any suggestions? I'm just guessing with this so I know some of them are wrong...
Sorry that this isn't a direct answer to your question but I think this needs pointing out. I think you may have misunderstood the purpose of the integer in brackets after the column type.
For VARCHAR types, as you probably already know, it restricts the maximum length. However it doesn't affect the number of bytes used for storage of a specific string. A string of length 5 will require the same number of bytes storage whether it is stored in a VARCHAR(100) or a VARCHAR(200).
For integral types the number has nothing at all to do with the number of bytes of storage. It is the display width, which is something else. See the manual:
Another extension is supported by MySQL for optionally specifying the display width of integer data types in parentheses following the base keyword for the type (for example, INT(4)). This optional display width may be used by applications to display integer values having a width less than the width specified for the column by left-padding them with spaces. (That is, this width is present in the metadata returned with result sets. Whether it is used or not is up to the application.)
The display width does not constrain the range of values that can be stored in the column, nor the number of digits that are displayed for values having a width exceeding that specified for the column.
Number (either 0 or 1) --> TINYINT(1) Unsigned
That should be a Boolean.
You've got it pretty sensible already.
Please note, you can't optimize anything with column types. With indexes you do.
Depends on your definition of "efficient". For speed, CHAR can be faster than VARCHAR (since each row ends up the same length, making it simple to seek to a given record). But all of your fields have to have fixed lengths, or don't bother.