# Типы данных и наборы символов **Наборы символов:** Список установленных наборов ``` SHOW CHARACTER SET; ``` По умолчанию utf 8mb4 varchar(20) character set latinl : при создании таблицы другой набор набор по-умолчанию для всей таблицы ``` create database european_sales character set latinl; ``` **Общая информация** - M максимальное количество. Для целых - кол-во цифр, для дробных - общее кол-во цифр, для строк макс. кол-во символов - D кол-во цифр после запятой, должно быть не больше M-2 - fsp применимо к дате/времени, определяет точность (кол-во дробной части секунды) - при strict mode перебор значения вызывает исключение, при restrictive - максимально возможное значение
ТипДоп. информация
char(255 символов) varchar(65535) char(20) 20 символов char фиксировано, при хранении добавляет справа PAD символы
tinytext(255) text(65535) mediumtext(16 млн) longtext(4 млр) если больше, то обрежутся конечные пробелы считаются при сортировке первые 1024 байта, но можно увеличить tinytext, text - можно не использовать
tinyint(1) smallint(2) mediumint int bigint(8) указано кол-во байтов при создании указывается визуальное кол-во цифр+один символ на знак ```sql CREATE TABLE employees (salary INTEGER(5) UNSIGNED); ``` int максимум 10, поэтому это преобразуется в int(11) ```sql CREATE TABLE employees (id INT(255)); ``` ZEROFILL заполняет 0 слева. ```sql CREATE TABLE documents (document_no INT(5) ZEROFILL); ```
DECIMAL = NUMERICфиксированное кол-во цифр. Равно int с коэффициентом деления. Первая цифра - общее кол-во цифр (M), вторая - кол-во цифр после запятой. Знак неявно добавляется. Т.е. от -9.99 до 9.99 ```sql CREATE TABLE taxes (tax_rate DECIMAL(3, 2)); ``` M < 65, по-умолчанию 10 при переборе ошибка, при выходе за пределы точности - округление по математическим правилам способ вывода больших чисел с игнором младших цифр ```sql select truncate(tax_rate * 1000, 0) from taxes; ``` в агрегатных функциях работает общее ограничение на 64 цифры, вычисление точное.
float, doubleприближенные числа отображаются как были внесены, но в агрегатных функциях могут появиться неточности ```sql CREATE TABLE typed_numbers( id TINYINT, float_values FLOAT, decimal_values DECIMAL(3, 2)); INSERT INTO typed_numbers VALUES (1, 1.1, 1.1), (2, 1.1, 1.1), (3, 1.1, 1.1); SELECT * FROM typed_numbers; | id | float_values | decimal_values | +------+--------------+------------------+ | 1 | 1.1 | 1.10 | | 2 | 1.1 | 1.10 | | 3 | 1.1 | 1.10 | SELECT SUM(float_values), SUM(decimal_values) FROM typed_numbers; | SUM(float_values) | SUM(decimal_values) | +--------------------+---------------------+ | 3.3000000715255737 | 3.30 | ``` Нельзя напрямую сравнивать в агрегатах, нужно сравнивать разницу ABS(v1 - v2) > 0.1 ```sql SELECT id, SUM(col1) as v1, SUM(col2) as v2 FROM temp GROUP BY id HAVING v1 <> v2; ``` нельзя, внешне одинаковые числа будут разными
битовый типcolumn\_name BIT(M) ``` CREATE TABLE bit_values (val BIT(7)); INSERT INTO bit_values VALUES(b'1011'); - равно VALUES(b'0001011'), в этой нотации b и B равны. INSERT INTO bit_values VALUES(0b1011); INSERT INTO bit_values VALUES(2); - автоматическое преобразование числа в битовую маску ``` select выводит в виде 0x0A select bin(...) - без 0 слева select lpad(bin(...), 7, '0') - привычный вид с 0 слева
date datetime timestamp year time 00-00-0000 вместо NULL, не отображается ```sql %а Краткое имя дня недели - Sun, Mon, ... %b Краткое имя месяца — Jan, Feb, ... %с Числовое значение месяца (0..11) %d Числовое значение дня месяца (00..31) %f Число микросекунд (000000..999999) %Н Час дня в 24-часовом формате (00..23) %h Час дня в 12-часовом формате (01..12) %i Минуты в часе (00..59) %j День года (001..366) %М Полное имя месяца (January..December) %m Числовое значение месяца %р AM или РМ %s Число секунд (00..59) %W Полное имя дня недели (Sunday..Saturday) %w Числовое значение дня недели (0=Sunday..6=Saturday) %Y Значение года (четыре цифры) ``` timestamp зависит от time\_zone ```sql CREATE TABLE datetime_temp(ts TIMESTAMP, dt DATETIME); INSERT INTO datetime_temp VALUES(NOW(), NOW()); SELECT ts, dt FROM datetime_temp; | 2017-10-14 18:10:25 | 2017-10-14 18:10:25 | SET time_zone = '+03:00'; SELECT ts, dt FROM datetime_temp; | 2017-10-14 21:10:25 | 2017-10-14 18:10:25 | ``` Если сервер MAXDB mode, TIMESTAMP = DATETIME column\_name TIME; ``` 838:59:59 to 838:59:59 + 6 цифр миллисекунд некорректное в 00:00:00, нельзя отличить от корректно добавленного 00:00:00 ```