Выбрать главу

Подробно свойства типов данных, такие, как размер, точность и диапазон возможных значений, описаны в табл. 4.1 в [1], поэтому повторяться здесь не будем. Далее кратко рассмотрим основные особенности типов данных и сосредоточимся на их возможном применении.

Целочисленные типы

К целочисленным типам относятся SMALLINT и INTEGER. Надо сказать, что SMALLINT представляет собой урезанную версию INTEGER и имеет длину 2 байта, в отличие от 4 байт, выделяемых для хранения INTEGER. Обычно экономить на дисковом пространстве не следует, и поэтому общей рекомендацией будет использовать для хранения целых значений тип INTEGER.

Область применения целочисленных типов очевидна: они нужны для полей, содержащих только целые числа - для хранения счетчиков, количества и т.д. Обычно тип INTEGER имеют также поля, содержащие первичные ключи.

Вещественные типы данных

К вещественным типам (их еще называют типами чисел с плавающей точкой) относятся FLOAT и DOUBLE PRECISION. Сразу следует предостеречь читателя от использования типа FLOAT - его точность недостаточна для хранения большинства дробных значений. Особенно не рекомендуется хранить в нем денежные величины - в переменных типа FLOAT очень быстро нарастают ошибки округления, что может сильно удивить бухгалтера при подведении итогов.

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

Надо отметить, что в 3-м диалекте InterBase для хранения денежных величин существует механизм хранения типов с фиксированной точкой длиной 64 бита. Использование этих типов обеспечивает наилучшую точность.

Типы данных с фиксированной точкой

К этим типам данных относятся NUMERIC и DECIMAL. Часто звучит вопрос, чем NUMERIC отличается от DECIMAL. Оба этих типа имеют одинаковую разрядность - от 1 до 18 знаков, одинаковую точность - от нуля до разрядности.

Напомним, что разрядность - это общее число цифр в числе, а точность - число знаков после запятой

Самое забавное, что. несмотря на то что в документации написано, что эти типы отличаются максимальной разрядностью, на самом деле реализованы они практически одинаково и разницы между ними никакой нет! Вы легко можете это проверить, запустив утилиту isql и произведя нижеследующую очередность действий.

Создаем таблицу следующего вида:

SQL> CREATE TABLE test (

CON> Num_field NUMERIC(15,2),

CON> Dec_field DECIMAL(15,2));

Затем даем команду показать структуру таблицы:

SQL> show tables test;

И наблюдаем такую картину:

NUM_FIELD NUMERIC(15, 2) Nullable

DEC_FIELD NUMERIC(15, 2) Nullable

Как видите. InterBase сообщает о том. что оба данных столбцы имеют тип NUMERIC!

Причины такого поведения лежат в реализации типов данных с фиксированной точкой. Дело в том, что InterBase имеет всего 3 механизма хранения любого целочисленного выражения, и все типы, как бы они ни назывались, приводятся к этим вариантам реализации.

Вот таблица из [1], которая иллюстрирует, как хранятся различные целочисленные типы (табл. 1.1). Как видите, хранение данных в 3-м диалекте отличается для чисел с большой разрядностью:

Хранение чисел с фиксированной точкой

Разрядность

Диалект 1

Диалект З

От 1 до 4

SMALLINT для NUMERIC INTEGER для DECIMAL

SMALLINT

От 5 до 9

INTEGER

INTEGER

От 10 до 18

DOUBLE PRECISION

INT64

Итак, теперь мы точно можем сказать, чем отличаются типы NUMERIC и DECIMAL: в случае определения поля (переменной) с малой разрядностью (до четырех) первый хранится в виде 2 байтового целого числа SMALLINT, а второй - в виде 4 байтового INTEGER.

Таким образом, в случае разрядности, большей четырех, типы DECIMAL и NUMERIC окажутся абсолютно эквивалентными!

Обратите внимание на отличие реализации типов с большой разрядностью в 1-м и 3-м диалектах. В 1-м диалекте число с фиксированной точкой превращалось из целого в вещественное, к которому применялись механизмы округления! В 3-м диалекте эта странность была ликвидирована - большие целые числа хранятся действительно как целые - с использованием механизма INT64, который может хранить 64-битовые числа в диапазоне +/- 2Л32. Поэтому рекомендуется хранить данные о денежных средствах в базах данных, созданных с использованием 3-го диалекта, - только при использовании механизма INT64 можно гарантировать сохранность малых денежных остатков.

Типы для хранения даты и времени

Типы для хранения даты и времени изменились в версии InterBase 6.x и его клонах по сравнению с 4.x и 5.x. Чтобы не путаться в исторических хитросплетениях с этими типами, рассмотрим ситуацию именно в 6-й версии InterBase, а затем на основе этого кратко упомянем о том, что было раньше, - это делается для тех пользователей, кто все еще работает на ранних версиях InterBase

Итак, в InterBase 6.x существует 3 типа для хранения даты и времени - это DATE, TIME и ТГМЕ8ТАМР.

* Тип DATE хранит даты с точностью до дня. Диапазон возможных значений - от 1 января 100 года н. э. до 29 февраля 32768 года.

* Тип TIME хранит данные о времени с точностью до десятитысячной доли секунды. Диапазон возможных значений - от 00:00 AM до 23:59.9999 РМ.

* Тип TIMESTAMP представляет собой комбинацию типов DATE и TIME.

Как работать с датами? Если речь идет о работе на уровне сервера в хранимых процедурах или триггерах, то все достаточно просто - мы всегда можем объявить переменную нужного нам типа и присваивать ей значения из таблиц и наоборот. Однако необходимо передавать данные из базы данных в приложение и обратно. В этом случае есть два подхода - либо использовать библиотеки, которые применяют оригинальный формат дат InterBase для доступа к объектам этих типов и преобразуют этот формат в привычные внутриязыковые типы даты/времени (примером такой библиотеки является FIBPlus), либо использовать механизм преобразования дат в строки, встроенный в InterBase.

Что делать, если нужно вырезать из полной даты только год или месяц? Для этого используется группа функций EXTRACT (доступная во всех клонах InterBase 6.x), которая позволяет выделить из даты только нужную часть. Используются эти функции следующим образом:

EXTRACT (MONTH FROM DATE_FIELD)

EXTRACT (YEAR FROM DATE_FIELD)

Полный список параметров в функции EXTRACT таков: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, WEEKDAY, YEARDAY. Их назначение очевидно следует из их названия, поэтому не будем приводить здесь расшифровки.

Типы данных для хранения текста

В InterBase существует два типа, предназначенных для хранения текстовой информации - CHAR и VARCHAR. Полные их названия, - CHARACTER и CHARACTER VARYING, однако нет никакой причины пользоваться длинными именами - даже команда Show tables в утилите isql выдает краткие наименования типов.

Чтобы определить поле или переменную символьного типа, необходимо в скобках после имени типа либо указать число символов, которое будет использоваться в определяемом объекте, либо опустить число символов - при этом будет создано поле с длиной 1 символ.

CREATE TABLE testCHARLen(

Fieldl CHAR(255),

Field2 CHAR);

В результате создания этой таблицы поле Fieldl будет иметь длину 255 символов, a Field2 - 1 символ.

Типы CHAR и VARCHAR во многом схожи - оба могут содержать до 32768 символов, однако есть и отличия. Хотя хранятся эти два типа в базе данных одинаково, но работает с ними InterBase по-разному. Это можно продемонстрировать следующим примером: