6.2.1 Числовые типы данных
MySQL поддерживает все числовые типы данных языка SQL92 по стандартам
ANSI/ISO. Они включают в себя типы точных числовых данных (NUMERIC
,
DECIMAL
, INTEGER
и SMALLINT
) и типы приближенных числовых данных (FLOAT
,
REAL
и DOUBLE PRECISION
). Ключевое слово INT
является синонимом для
INTEGER
, а ключевое слово DEC
- синонимом для DECIMAL
.
Типы данных NUMERIC
и DECIMAL
реализованы в MySQL как один и тот же тип -
это разрешается стандартом SQL92. Они используются для величин, для
которых важно сохранить повышенную точность, например для денежных данных.
Требуемая точность данных и масштаб могут задаваться (и обычно задаются)
при объявлении столбца данных одного из этих типов, например:
salary DECIMAL(5,2)
В этом примере - 5
(точность) представляет собой общее количество значащих
десятичных знаков, с которыми будет храниться данная величина, а цифра 2
(масштаб) задает количество десятичных знаков после запятой.
Следовательно, в этом случае интервал величин, которые могут храниться в
столбце salary
, составляет от -99,99
до 99,99
(в действительности для
данного столбца MySQL обеспечивает возможность хранения чисел вплоть до
999,99
, поскольку можно не хранить знак для положительных чисел).
В SQL92 по стандарту ANSI/ISO выражение DECIMAL(p)
эквивалентно
DECIMAL(p,0)
. Аналогично, выражение DECIMAL
также эквивалентно
DECIMAL(p,0)
, при этом предполагается, что величина p
определяется
конкретной реализацией. В настоящее время MySQL не поддерживает ни одну из
рассматриваемых двух различных форм типов данных DECIMAL/NUMERIC
. В общем
случае это не является серьезной проблемой, так как основные преимущества
данных типов состоят в возможности явно управлять как точностью, так и
масштабом представления данных.
Величины типов DECIMAL
и NUMERIC
хранятся как строки, а не как двоичные
числа с плавающей точкой, чтобы сохранить точность представления этих
величин в десятичном виде. При этом используется по одному символу строки
для каждого разряда хранимой величины, для десятичного знака (если масштаб > 0
)
и для знака `-' (для отрицательных чисел). Если параметр масштаба
равен 0
,
то величины DECIMAL
и NUMERIC
не содержат десятичного знака или дробной
части.
Максимальный интервал величин DECIMAL
и NUMERIC
тот же, что и для типа
DOUBLE
, но реальный интервал может быть ограничен выбором значений
параметров точности
или масштаба
для данного столбца с типом данных DECIMAL
или NUMERIC
. Если конкретному столбцу присваивается значение, имеющее
большее количество разрядов после десятичного знака, чем разрешено
параметром масштаба
, то данное значение округляется до количества разрядов,
разрешенного масштаба
. Если столбцу с типом DECIMAL
или NUMERIC
присваивается значение, выходящее за границы интервала, заданного
значениями точности
и масштаба
(или принятого по умолчанию), то MySQL
сохранит данную величину со значением соответствующей граничной точки
данного интервала.
В качестве расширения стандарта ANSI/ISO SQL92 MySQL также поддерживает
числовые типы представления данных TINYINT
, MEDIUMINT
и BIGINT
, кратко
описанные в таблице выше. Еще одно расширение указанного стандарта,
поддерживаемое MySQL, позволяет при необходимости указывать количество
показываемых пользователю символов целого числа в круглых скобках,
следующих за базовым ключевым словом данного типа (например INT(4)
). Это
необязательное указание количества выводимых символов используется для
дополнения слева выводимых значений, которые содержат символов меньше, чем
заданная ширина столбца, однако не накладывает ограничений ни на диапазон
величин, которые могут храниться в столбце, ни на количество разрядов,
которые могут выводиться для величин, у которых количество символов
превосходит ширину данного столбца. Если дополнительно указан
необязательный атрибут ZEROFILL
, свободные позиции по умолчанию
заполняются нолями. Например, для столбца, объявленного как INT(5)
ZEROFILL
, величина 4
извлекается как 00004
. Следует учитывать, что если в
столбце для целых чисел хранится величина с количеством символов,
превышающим заданную ширину столбца, могут возникнуть проблемы, когда
MySQL будет генерировать временные таблицы для некоторых сложных связей,
так как в подобных случаях MySQL полагает, что данные действительно
поместились в столбец имеющейся ширины.
Все типы целочисленных данных могут иметь необязательный и не оговоренный
в стандарте атрибут UNSIGNED
. Беззнаковые величины можно использовать для
разрешения записи в столбец только положительных чисел, если необходимо
немного увеличить числовой интервал в столбце.
В версии MySQL 4.0.2 числовые типы данных с плавающей точкой также могут
иметь параметр UNSIGNED
. Как и в целочисленных типах, этот атрибут
предотвращает хранение в отмеченном столбце отрицательных величин. Но, в
отличие от целочисленных типов, максимальный интервал для величин столбца
остается прежним.
Тип FLOAT
обычно используется для представления приблизительных числовых
типов данных. Стандарт ANSI/ISO SQL92 допускает факультативное указание
точности (но не интервала порядка числа) в битах в круглых скобках,
следующих за ключевым словом FLOAT
. Реализация MySQL также поддерживает
это факультативное указание точности. При этом если ключевое слово FLOAT
в
обозначении типа столбца используется без указания точности, MySQL
выделяет 4 байта для хранения величин в этом столбце. Возможно также иное
обозначение, с двумя числами в круглых скобках за ключевым словом FLOAT
. В
этом варианте первое число по-прежнему определяет требования к хранению
величины в байтах, а второе число указывает количество разрядов после
десятичной запятой, которые будут храниться и показываться (как для типов
DECIMAL
и NUMERIC
). Если в столбец подобного типа попытаться записать
число, содержащее больше десятичных знаков после запятой, чем указано для
данного столбца, то значение величины при ее хранении в MySQL округляется
для устранения излишних разрядов.
Для типов REAL
и DOUBLE PRECISION
не предусмотрены установки точности.
MySQL воспринимает DOUBLE
как синоним типа DOUBLE PRECISION
- это еще
одно расширение стандарта ANSI/ISO SQL92. Но, вопреки требованию
стандарта, указывающему, что точность для REAL
меньше, чем для DOUBLE
PRECISION
, в MySQL оба типа реализуются как 8-байтовые числа с плавающей
точкой удвоенной точности (если не установлен ``ANSI-режим''). Чтобы
обеспечить максимальную совместимость, в коде, требующем хранения
приблизительных числовых величин, должны использоваться типы FLOAT
или
DOUBLE PRECISION
без указаний точности или количества десятичных знаков.
Если в числовой столбец попытаться записать величину, выходящую за границы
допустимого интервала для столбца данного типа, то MySQL ограничит
величину до соответствующей граничной точки данного интервала и сохранит
результат вместо исходной величины.
Например, интервал столбца INT
составляет от -2147483648
до 2147483647
.
Если попытаться записать в столбец INT
число -9999999999
, то оно будет
усечено до нижней конечной точки интервала и вместо записываемого значения
в столбце будет храниться величина -2147483648
. Аналогично, если
попытаться записать число 9999999999
, то взамен запишется число
2147483647
.
Если для столбца INT
указан параметр UNSIGNED
, то величина допустимого
интервала для столбца останется той же, но его граничные точки сдвинутся к
0
и 4294967295
. Если попытаться записать числа -9999999999
и 9999999999
,
то в столбце окажутся величины 0
и 4294967296
.
Для команд ALTER TABLE
, LOAD DATA INFILE
, UPDATE
и многострочной INSERT
выводится предупреждение, если могут возникнуть преобразования данных
вследствие вышеописанных усечений.