Which data types should I use? - mysql

I am unsure of which data types to use for the following attributes:
A phone number (which is made up of 10 numbers)
A client name
A numeric product ID that acts as a Primary Key
The location/state of the client (which only has 1 out of 8 possible values)
Im not sure of whether to use CHAR or VARCHAR for some of these, or if there is another type I should use.

INTEGER (Always used for numeric numbers)
(If you are allowing "+" & etc. use VARCHAR)
CHAR (for characters)
INTEGER (as mentioned above)
VARCHAR (It accepts both the character and the number)
Note: You should use "varchar" for all you needs.

phone number -> decimal(10, 0)
name -> varchar(length)
productId -> integer unsigned (you can use autoincrement)
location -> enum('possible value 1', 'possible value 2', ...)

Understanding the difference between Char, Varchar will help you out.
Char is fixed length.
Varchar is variable-length.
So in case, you have some fixed length variables like Gender, you can go with char, If you have some variable length variable like Name in your case, you can go with Varchar.

Related

What does `NUMERIC maxsize 256` mean in mysql?

Here is a data fields definition:
Field Name
Field Description
Field Type (format)
Max Size
May be NULL
Key
tag
The unique identifier (name) for a tag in a specific taxonomy release.
ALPHANUMERIC
256
No
*
version
For a standard tag, an identifier for the taxonomy; otherwise the accession number where the tag was defined.
ALPHANUMERIC
20
No
*
ddate
The end date for the data value, rounded to the nearest month end.
DATE (yyyymmdd)
8
No
*
qtrs
The count of the number of quarters represented by the data value, rounded to the nearest whole number. “0” indicates it is a point-in-time value.
NUMERIC
8
No
*
uom
The unit of measure for the value.
ALPHANUMERIC
20
No
*
coreg
If specified, indicates a specific co-registrant, the parent company, or other entity (e.g., guarantor).  NULL indicates the consolidated entity.
NUMERIC
256
Yes
*
value
The value. This is not scaled, it is as found in the Interactive Data file, but is limited to four digits to the right of the decimal point.
NUMERIC(28,4)
16
Yes
footnote
The text of any superscripted footnotes on the value, as shown on the statement page, truncated to 512 characters, or if there is no footnote, then this field will be blank.
ALPHANUMERIC
512
Yes
The field definition is SEC U.S. Securities and Exchange Commission's official material:
sec official material
For coreg ,it's field type is numeric ,max size 256 ,how to write the create statement?
CREATE TABLE `num` (
`id` INT NOT NULL AUTO_INCREMENT,
`tag` VARCHAR(256) NOT NULL,
`version` VARCHAR(20) NOT NULL,
`ddate` DATE NOT NULL,
`qtrs` DECIMAL(8) NOT NULL,
`uom` VARCHAR(20) NOT NULL,
`coreg` ?,
`value` DECIMAL(28,4),
`footnote` VARCHAR(512),
PRIMARY KEY (id)
);
To write the field definiton as below?
`coreg` NUMERIC(256)
In MySQL the maximum number of digits for decimal (numeric) type is 65.
So, you can't technically define a column as NUMERIC(256).
11.1.3 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC
The maximum number of digits for DECIMAL is 65
It doesn't really make sense to me to have the "the parent company, or other entity (e.g., guarantor)" defined as a number, even as a really long number.
Maybe there is a typo and really it should read "ALPHANUMERIC", i.e. a text value.
If this value will never be interpreted as a number and there will never be attempts to make some calculations with this number (as the field description implies), then it should be stored as a text (varchar(256)); maybe with some extra checks that you can store only digits 0-9 and not any symbol there.
It probably means it's just a long sequence of digits. You would typically store it as a NUMERIC but a size of 256 digits is beyond MySQL's limit for numeric types. You can store it, however, as a VARCHAR(256) and add a CHECK constraint on it.
Note: CHECK constraints are enforced only in MySQL 8.0 (8.0.3?) and newer.
For example:
create table t (
coreg varchar(256) check (coreg regexp '^[0-9]+$')
);
insert into t (coreg) values ('123');
insert into t (coreg) values ('x456'); -- fails
insert into t (coreg) values ('7y89'); -- fails
insert into t (coreg) values ('012z'); -- fails
insert into t (coreg) values ('345 '); -- fails
See running example in db<>fiddle.

Best index selection for storing Country Code + Phone

I have 3 choices to store 2 fields: country code + phone
a) country code (can be 1, 2 or 3 characters)
b) phone (can be 8-12 digits)
These 2 fields will be used to create a 2-field index:
varchar(3) and varchar(12)
char(3) and char(12) -- but waste of space for char(12)?
smallint and varchar(12)
smallint and char(12) -- but waste of space for char(12)?
Which one should I choose for index efficiency?
would a SmallInt + varchar slow index down, or string fields should pair with string fields?
Grateful for any advice anyone can offer.
You have described two non-number fields that can have up to 3 and 12 characters each. The first choice seems like the obvious choice.
I say these are non-number fields because arithmetic and (generally) comparison logic on the values would not follow numeric rules. It doesn't make sense to add 1 to either value.
In addition, it is quite possible that leading zeros are important.
If you are using ISO 3-character country codes, then you know the values are 3 characters, and you can use CHAR(3) instead of VARCHAR(3). Of course, a smallint would also be appropriate.

Precision loss when performing large number operation in mysql

In MySQL 5.7, a table defined as following shown
CREATE TABLE `person` (
`person_id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(64) DEFAULT NULL,
PRIMARY KEY (`person_id`),
KEY `ix_name` (`name`)
) ENGINE=InnoDB CHARSET=utf8
And then we prepared two records for testing, the value of name field (with varchar type) are
123456789123456789
1
respectively.
Case 1
select * from person where name = 123456789123456789-1;
Note that we are using a number instead of string inside the where clause. The record with name 123456789123456789 returned, and it seemed that -1 in the end are ignored!
Furthermore, we add another record with name = 123456789123456788, and this time the above select returns two records, including both 123456789123456789 and 123456789123456788;
The output looks so strange!
Case 2
select * from person where name = 123456789123456789-123456789123456788;
We could get the record with name 1, and in this case it seems that the - act as a minus operator.
Why the behavior of - in two cases are so different!
I can't immediately tell you what the type of 123456789123456789-1 is but for the comparison operation, we're almost certainly falling through most of the more "normal" data type conversion rules for mysql and ending up at:
In all other cases, the arguments are compared as floating-point (real) numbers.
Because one of the argument for the comparison (name) is a string type and the other is numeric, nothing else matches. So both get converted to floats and float types don't have too many digits of precision. Certainly less than the 18 required to represent 123456789123456789 and 123456789123456788 as two different numbers.
Look here:
SELECT person_id, name, name + 0.0, 123456789123456789-1 + 0.0, name = 123456789123456789-1
FROM person
ORDER BY person_id;
Perhaps, before comparing name = 123456789123456789-1 MySQL converts name and 123456789123456789-1 to DOUBLE as I showed in select. So some digits are lost.
Demo.

How does mysql do multi-type comparison?

I was working on a project and due to a miscomprehension, we ended up comparing a stored int with a string in a MySql database. I ran a few test and it seems to work but I would like to know how MySql compares different datatypes.
Does it convert one to the other? If it does does it convert both to strings or to ints?
When you use a string in an integer context, for example in an arithmetic expression or in a comparison to an integer, MySQL takes the numeric value of that string as a DOUBLE data type.
See https://dev.mysql.com/doc/refman/5.7/en/type-conversion.html
Demonstration:
mysql> create table foo as select 1+'1' as x;
mysql> show create table foo\G
CREATE TABLE `foo` (
`x` double NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1
The numeric value of a string is the numeric value of any leading digit characters or other characters that make a floating-point number, like -+.e.
For example, the numeric value of '123abc' is 123.
Scientific notation is supported.
mysql> select 1 + '5e-2xyz' as n;
+------+
| n |
+------+
| 1.05 |
+------+
If there are no leading characters that form a numeric value, the string's numeric value is 0.
Mysql manual has a complete section dedicated to this, called Type Conversion in Expression Evaluation.
When an operator is used with operands of different types, type conversion occurs to make the operands compatible. Some conversions occur implicitly. For example, MySQL automatically converts numbers to strings as necessary, and vice versa.
If you compare an int with a string, then both values are converted to floating point number and compared thus.

Out of range value for column 'contact_no' at row 1

I was trying to add a number with a length of 11 but when I input it in the database it can't. If I try to add a number with a length of 10 it can.
This is the error:
ERROR 1264: 1264: Out of range value for column 'contact_no' at row 1
SQL Statement:
INSERT INTO `mcs`.`new_table` (`id`, `contact_no`) VALUES ('1', '12345678901')
It's not clear what question you are asking.
Why is this error being returned?
Likely, the contact_no column is declared with datatype of INT, a 32-bit integer, and you attempted to assign a value larger than the supported maximum value.
The maximum value for a signed 32-bit integer is 2,147,483,647. (that decimal value of 2^31-1. For an unsigned 32-bit integer, maximum value is 2^32.)
Some other question that wasn't asked
If you need to store values larger than the maximum supported by the INT datatype, you could define the column as a different datatype.
For example, BIGINT gives a maximum value of 2^63-1 for unsigned.
If you need a maximum of 12 decimal digits, you could use a DECIMAL(12) datatype.
Change your data type of contact_no to BIGINT.
Check range of different data type at MYSQL official website.
I personally recommend you to use varchar, as you don't need to compare contact number with any field.
Please check datatype of contact_no column.
'12345678901' is exceeding its size.