When should I use UNSIGNED attribute for a column exactly? - mysql

Based on documentation, UNSIGNED columns doesn't accept negative numbers. So is that mean should I use UNSIGNED attribute for each column which always is containing positive or null values?
Suppose this table structure:
// vote
+----+---------+---------+-------+------------+----------+
| id | id_post | id_user | value | code_table | time |
+----+---------+---------+-------+------------+----------+
In table above, all columns are null or positive except value column. So should I set UNSIGNED attribute for all columns except value column? Am I right? Or using UNSIGNED attribute is based on another parameter?

If you are sure that all the columns except the value column is going to contain positive values then yes you should set it as UNSIGNED. Using UNSIGNED attribute is based only on this parameter as what value you expect in your column. Also to note that UNSIGNED ranges from 0 to n wheras SIGNED ranges from about -n/2 to n/2.
On the side of memory both signed and unsigned types take the same memory space (4 bytes for INT).

Use UNSIGNED attribute based on the values you will store in the column.
The IDs, for example, are usually unsigned values (this is just a convention, nothing prevents you have negative ID values).
On the other hand, an age column will always contain positive values and the UNSIGNED value fits well for it.

Related

Is it logically correct to have an integer column of length 1 in SQL if we don't need leading zeros?

Let's say we have a simple table of 2 columns with two scenarios.
With ID column of length 10
CREATE TABLE `members` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
)
With ID column of length 1
CREATE TABLE `members` (
`id` int(1) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
)
Can I define the length of column ID by 1 if I don't need the leading zeros in the ID column?
I don't have an idea where the leading zeros are helpful and what are the cons if I define the length of the integer column by 1 if there is no need for leading zeros.
If you don't need leading zeroes, then simply do not use the ZEROFILL column option, which I see is already absent from your create table statement.
The "length" of an integer is meaningless except for display. It does not affect the storage size of the integer, or the maximum value that can be stored in it. The length is optional, and I always omit it.
Example:
CREATE TABLE `members` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
...
This has been the source of confusion for MySQL users for many years.
Finally in MySQL 8.0, they stopped outputting this misleading syntax when you use SHOW CREATE TABLE. Use of the integer length is discouraged.
The short answer is: You can set the zerofill length to 1 if you absolutely have no use of it. However, sometimes you may want your numbers to be neatly aligned . e.g Instead of displaying ID values from 1 all the way up to 9999, defining an int(4) zerofill makes the values show up from 0001 to 9999. That could be helpful in certain formal scenarios.

Why can't I change my INT from unsigned to signed? Is signed Zerofill possible?

I have a field called NUMBER in a table called TEST
NUMBER is int(8) Unsigned Zerofill Not Null
I need negative numbers in this field now and I'd still like them zerofilled
For example -00023419
I can change it to signed, but can't seem to get zerofilled.
if I do: alter table test modify number int(8) signed zerofill not null -
It stays unsigned zerofill
if I do: alter table test modify number int(8) zerofill not null -
It stays unsigned zerofill
if I do: alter table test modify number int(8) signed not null -
I get signed but no zerofill
When I had it set to signed, I put an a negative number then tried to change to zerofill and the number changed to 00000000 and everything was set to unsigned again. It it impossible to have signed zerofilled numbers?
https://dev.mysql.com/doc/refman/5.7/en/numeric-type-attributes.html says:
If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column.
Reported as a bug in 2006, closed as "Not a Bug".
https://bugs.mysql.com/bug.php?id=24356
Re your comment:
So does this mean no one out there has negative zero filled data in a mysql database?
Right. The most common use case for ZEROFILL is to make sure things like zip codes or bank account numbers use a fixed number of digits. These cases don't support negative values anyway, so why bother with ugly strings like -00001234?
can you convert it to zerofilled with PHP?
Yes, you can format numbers with zero-padding in PHP.
<?php
$n = -1234;
printf("Number is %08d\n", $n);
Output:
Number is -0001234
Read http://php.net/manual/en/function.sprintf.php for more neat formatting things you can do with printf()/sprintf().
ZEROFILL implies UNSIGNED.
MySQL Reference Manual https://dev.mysql.com/doc/refman/5.7/en/numeric-type-attributes.html
If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column.
With all the potential problems, I avoid using the non-standard MySQL ZEROFILL attribute.
Well, if your column is a foreign key or a primary key, MySQL doesn't allow this modification to happen. You have to do this beforehand.

MySQL - Default value in field type INT

I have a question I'd like to help me solve, it's about the values of the data type in the fields of the database.
It is mandatory to specify the number of characters or values that will have a field identifier id INT.
id INT UNSIGNED NOT NULL AUTO_INCREMENT
What is the difference between id INT and id INT(11), It is mandatory to establish a number of values?.
id INT UNSIGNED NOT NULL AUTO_INCREMENT
id(11) INT UNSIGNED NOT NULL AUTO_INCREMENT
What is the default setting MySQL in id INT, if not specify any value?
What is the maximum amount exact numbers that allows me to add INT
In that case you must use INT
In that case you should use BIGINT
Example: I will take an example of a news portal, that I could receive many visits.
Need to record the number of times it is accessed worldwide news, let's say your news year is visited 999.999.999 times, is a bit exaggerated know :), but it is valid to use in this case INT or BIGINT
I much appreciate your support.
According to 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.)
And according to Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT:
The datatype INT uses 4 bytes (from -2147483648 to 2147483647 or unsigned from 0 to 4294967295), the datatype BIGINT uses 8 bytes (from -9223372036854775808 to 9223372036854775807 or unsigned from 0 to 18446744073709551615).
So the answers to your questions in my opinion are:
Ad 1) No.
Ad 2) The display with as described above.
Ad 3) No display width will be specified.
Ad 3) The display with will be set to the default value for datatype INT. That is 10 for unsigned and 11 for signed (signed has more to allow space for a leading dash character, the minus sign, for negative values).
Thanks spencer7593 for the correction.
Ad 4) See above.
Ad 5 and 6) Up to 2147483647 you can use INT, above that value you can must either use unsigned INT or BIGINT.
It is mandatory to specify the number of characters or values that will have a field identifier id INT.
id INT UNSIGNED NOT NULL AUTO_INCREMENT
ANS: In the Database the primary key begins at one and increments by one. So 1,2, ... For this reason, you do not have to specify UNSIGNED
What is the difference between id INT and id INT(11), It is mandatory to establish a number of values?.
id INT UNSIGNED NOT NULL AUTO_INCREMENT
// the (11) would be on the datatype, not the name of the column.
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT
ANS: When you specify the limit, that is the maximum number of characters it can go. The maximum for an INT is 2147483647. In an INT, the limit does not affect
What is the default setting MySQL in id INT, if not specify any value?
ANS: the Default for an INT is 0 unless it is a Primary Key, in which case it is a 1
What is the maximum amount exact numbers that allows me to add INT?
In that case you must use INT
Ans: For Primary Keys or for a column in which you always want a whole number. Example: Quantity of something.
In that case you should use BIGINT
Ans:You can use BIGINT for when the number is a lot more than what an INT can hold
You can refer to http://dev.mysql.com/doc/refman/5.7/en/integer-types.html

What is the actual range of a MySQL INT column in this situation?

Ok, so I know that the INT type in MySQL has a range of either 0 to 4,294,967,295 or of -2,147,483,648 to 2,147,483,647
MySQL reference
My question is if I have a single row in an INT column with a value of -1 and all other rows are positive numbers, what is the actual range of that column? Because it has a single negative number, does the column automatically have a range of -2,147,483,648 to 2,147,483,647, or is the range more dynamic and instead is -1 to 4,294,967,294?
So to be more specific about the INT datatype; you can have either INT UNSIGNED or INT SIGNED. This is set when the column is created. I believe it defaults to SIGNED if you don't specify. So any INT column is either SIGNED or UNSIGNED and this is NOT dynamic.
INT UNSIGNED has the range 0 to 4,294,967,295
INT SIGNED has the range -2,147,483,648 to 2,147,483,647
So if even one row has a negative value, you have to use INT SIGNED. Giving the column the range -2,147,483,648 to 2,147,483,647.
The ranges you are seeing in the MySQL reference are describing whether or not you add in SIGNED (the default if left blank) or UNSIGNED as an attribute in your column definition. E.g., CREATE TABLE my_table(column_1 INT UNSIGNED...).
If you specify UNSIGNED you extend the upper bound of the data type (assuming the data type in question has a SIGNED/UNSIGNED option), but you also lose the lower end of the range. If you specify SIGNED or don't specify anything at all (then the default SIGNED will apply) then your upper bound is the upper bound of the SIGNED range.
So, for a SIGNED column of type INT (or if no attribute is specified), your range is -2,147,483,648 to 2,147,483,647. If you specify UNSIGNED your range is 0 to 4,294,967,295, and you would not actually be able to put -1 in that column and have it be properly stored as -1. Per http://dev.mysql.com/doc/refman/5.1/en/out-of-range-and-overflow.html, MySQL "stores the value representing the corresponding endpoint of that range" for integers. So inserting -1 into an UNSIGNED integer column will store 0 instead. If you need to store negative integer values, you need to use SIGNED. If you need an extended upper range and don't need to store negative numbers, you would want to use the UNSIGNED attribute.
The range of 0 to 4,294,967,295 is for UNSIGNED. As an example:
...
`type` int(10) UNSIGNED NOT NULL DEFAULT '0'
...
You have to specifically set the unsigned state for the column otherwise it is considered signed which will have the range of -2,147,483,648 to 2,147,483,647
No, the ranges are not dynamically adjusted to the filled data. SIGNED and UNSIGNED ranges are raw ranges, regardless what the table already contains.
CREATE TABLE `testing` (
`x` INT(11) NULL DEFAULT NULL
)
ENGINE=InnoDB
;
INSERT INTO testing VALUES (-1);
SELECT * FROM testing;
INSERT INTO testing VALUES (4000000000);
SELECT * FROM testing;
Returns "Out of range error", and data will be "-1 ; 2147483647" (greatest SIGNED INT 32 bits)

MySQL: Using an Integer with Auto Increment as primary key - should I declare it as unsigned?

When creating a table, I often use an INTEGER column with AUTO_INCREMENT as primary key (surrogate key), like so:
CREATE TABLE 'my_table' (
user_id INTEGER AUTO_INCREMENT PRIMARY KEY,
[…]
);
(Note that the ellipsis is only there to focus the example on whats important.)
Now I've read that INTEGER columns can hold an integer from -2,147,483,648 to 2,147,483,647 and from 0 to 4,294,967,295 when unsigned.
Since user_id will always be unsigned (MySQL starts counting from 0 if I am not mistaken), would it make sense to explicitly mark this column as UNSIGNED to allow more users stored in that table (4,294,967,295 instead of 2,147,483,647)?
According to http://dev.mysql.com/doc/refman/5.0/en/integer-types.html, the size of an UNSIGNED INT and a signed INT, so that won't make a difference in your choice. As far as I know, AUTO_INCREMENT starts at 1, so if you think you will need more than 2,147,483,647 rows, go for the unsigned int.
Unsigned allows for improvement in your queries based on that field.
Aside from that, there is no real difference
See the article at this link >> Signed vs Unsigned for more information as to why this is faster for queries.
Suppose the following query, where 'quantity' is the INT field.
SELECT *
FROM customer
WHERE quantity <= 500
If quantity IS NOT unsigned, then and quantity field is an “int” and you have an index of this field, MySQL will define the range as -2147483648 to 500 and it will get the result based on this range.
However, if the quantity field IS unsigned, then that range will be 0 - 500. A much smaller scope.
The only other convention that applies here is the actual storage of information. Unsigned since it's base is 0-4m, requires more storage as the binary count is higher. Where signed, is 0-2m with 1 bit to flag if it is positive or negative. This results in a smaller storage requirement.
SUMMARY
Use Signed if you want to save space.
Use Unsigned if you want speed.