Литвек - электронная библиотека >> Алексей В Паутов >> Базы данных >> MySQL: руководство профессионала >> страница 2
Это не совместимо с прикладными программами, полагающимися на старые версии MySQL, которые разрешали сохранять дополнительную цифру вместо знака +.

SQL-стандарт требует, чтобы точность NUMERIC(M,D) была точно M цифр. Для DECIMAL(M,D) стандарт требует точности по крайней мере M цифр, но позволяет больше. В MySQL DECIMAL(M,D) и NUMERIC(M,D) то же самое, и оба типа имеют точность ровно M цифр.

1.3. Обработка выражений

Числа с точным значением используются как даны всякий раз, когда возможно. Например, числа в сравнениях используются точно как даны, без изменения в значении. В строгом SQL-режиме для INSERT в столбец с точным типом данных (DECIMAL или целое число), значение вставлено с точным значением, если оно внутри диапазона столбца. Когда значение получено, оно должно быть таким же как то, что было вставлено. Без строгого режима допустимо усечение для INSERT.

Обработка числового выражения зависит от значений, которое выражение содержит:


Если любые приблизительные значения присутствуют, выражение оценено приблизительно, используя арифметику с плавающей запятой.


Если никакие приблизительные значения не присутствуют, выражение содержит только точные значения. Если любое точное значение содержит дробную часть (значение после десятичной точки), выражение оценено, используя точную арифметику DECIMAL и имеет точность 65 цифр.


Иначе, выражение содержит только целочисленные значения. Выражение точно и оценено, используя целочисленную арифметику и имеет точность BIGINT (64 бита).

Если числовое выражение содержит любые строки, они преобразованы в значения с плавающей запятой двойной точности, и выражения приблизительны.

На вставки в числовые столбцы воздействует SQL-режим, который управляется переменной системы sql_mode. Следующее обсуждение упоминает строгий режим (выбранный значениями режима STRICT_ALL_TABLES или STRICT_TRANS_TABLES) и ERROR_FOR_DIVISION_BY_ZERO. Чтобы включить все ограничения, Вы можете просто использовать режим TRADITIONAL, который включает строгие значения режима и ERROR_FOR_DIVISION_BY_ZERO:


mysql> SET sql_mode='TRADITIONAL';


Если число вставлено в столбец точного типа (DECIMAL или целое число), оно вставлено с точным значением, если находится внутри диапазона столбца.

Если значение имеет слишком много цифр в дробной части, происходит округление, и будет сгенерировано предупреждение. Округление выполнено как описано в разделе " 1.4. Поведение округления".

Если значение имеет слишком много цифр в целочисленной части, оно слишком большое и обработано следующим образом:

Если строгий режим не допускается, значение усечено к самому близкому допустимому значению, и сгенерировано предупреждение.

Если строгий режим допускается, происходит ошибка переполнения.


По умолчанию, деление на нуль производит результат NULL и никакого предупреждения. С включенным режимом SQL ERROR_FOR_DIVISION_BY_ZERO MySQL обрабатывает деление на нуль по-другому:


Если строгий режим не допускается, происходит предупреждение.

Если строгий режим допускается, вставки и модификации, включающие деление на нуль, запрещены, и происходит ошибка.


Другими словами, вставки и модификации, включающие выражения, которые выполняют деление на нуль, могут обрабатываться как ошибки, но это требует ERROR_FOR_DIVISION_BY_ZERO в дополнение к строгому режиму.

Предположим, что мы имеем эту инструкцию:


INSERT INTO t SET i = 1/0;


Это что случается для комбинации строгого режима и ERROR_FOR_DIVISION_BY_ZERO:


Значение sql_mode | Результат


'' (значение по умолчанию) | Никаких предупреждений и ошибок: i установлен в NULL.

strict | Никаких предупреждений и ошибок: i установлен в NULL.

ERROR_FOR_DIVISION_BY_ZERO | Никаких ошибок, но есть предупреждение: i установлен в NULL.

strict,ERROR_FOR_DIVISION_BY_ZERO | Ошибка: никакая строка не вставлена.


Для вставок строк в числовые столбцы, преобразование из строки в число обработано следующим образом, если строка имеет нечисловое содержание:


Строка, которая не начинается с числа, не может использоваться как число, и производит ошибку в строгом режиме или предупреждение в любом другом. Это включает пустую строку.

Строка, которая начинается с числа, может быть преобразована, но конечная нечисловая часть усечена. Если усеченная часть содержит что-нибудь другое, чем пробелы, это производит ошибку в строгом режиме или предупреждение в любом другом.

1.4. Поведение округления

Этот раздел обсуждает точность математического округления для функции ROUND() и для вставок в столбцы с типами с точным значением.

Функция ROUND() работает по-разному в зависимости от того, является ли параметр точным или приблизительным числом:


Для числа точного значения ROUND() использует метод "округления половины": значение с дробной частью .5 или больше округлено до следующего целого числа, если положительное, или до предыдущего целого числа, если отрицательное. Значения с дробной частью меньше, чем .5, округлены до предыдущего целого числа, если положительные, или до следующего, если отрицательные.


Для числа приблизительного значения результат зависит от библиотеки C. На многих системах это означает, что значение с любой дробной частью округлено ROUND() к самому близкому четному целому числу.

Следующий пример показывает, как округление отличается для точных и приблизительных значений:


mysql> SELECT ROUND(2.5), ROUND(25E-1);

+------------+--------------+

| ROUND(2.5) | ROUND(25E-1) |

+------------+--------------+

| 3 | 2 |

+------------+--------------+


Для вставок в DECIMAL или целочисленный столбец, если адресат представляет собой точный тип данных, используется метод "округления половины" независимо от того, является ли значение, которое будет вставлено, точным или приблизительным:


mysql> CREATE TABLE t (d DECIMAL(10,0));

Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO t VALUES(2.5),(2.5E0);

Query OK, 2 rows affected, 2 warnings (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 2


mysql> SELECT d FROM t;

+------+

| d |

+------+

| 3 |

| 3 |

+------+

1.5. Примеры математической точности

Этот раздел обеспечивает некоторые примеры, которые показывают запросы с математической точностью в MySQL 5.1.

Пример 1. Числа используются с их точным значением, как даны, когда возможно:


mysql> SELECT .1 + .2 = .3;

+--------------+

| .1 + .2 = .3 |

+--------------+

| 1 |

+--------------+


Для значений с плавающей запятой, результаты неточны:

mysql> SELECT .1E0 + .2E0 = .3E0;

+--------------------+

| .1E0 + .2E0 = .3E0 |

+--------------------+

| 0 |

+--------------------+


Другой способ увидеть различие в точной и приблизительной обработке значения состоит в том, чтобы добавить маленькое число к сумме много раз. Рассмотрите следующую сохраненную
ЛитВек: бестселлеры месяца
Бестселлер - Розамунда Пилчер - В канун Рождества - читать в ЛитвекБестселлер - Олег Вениаминович Дорман - Подстрочник: Жизнь Лилианны Лунгиной, рассказанная ею в фильме Олега Дормана - читать в ЛитвекБестселлер - Джон Перкинс - Исповедь экономического убийцы - читать в ЛитвекБестселлер - Людмила Евгеньевна Улицкая - Казус Кукоцкого - читать в ЛитвекБестселлер - Наринэ Юрьевна Абгарян - Манюня - читать в ЛитвекБестселлер - Мария Парр - Вафельное сердце - читать в ЛитвекБестселлер - Юрий Осипович Домбровский - Хранитель древностей - читать в ЛитвекБестселлер - Элияху Моше Голдратт - Цель-2. Дело не в везении  - читать в Литвек