СТАТЬЯ
11.03.01

предыдущая часть | содержание | следующая часть

ГЛАВА 3

ВЫБОР ТИПА ДАННЫХ

Эта глава обсуждает типы данных ORACLE, их свойства и их соответствие типам данных не-ORACLE. Темы этой главы включают обсуждение следующих вопросов:

Типы данных ORACLE

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

Символьные типы данных

Типы данных CHAR и VARCHAR2 хранят алфавитно-цифровые данные; в столбце одного из этих типов данных можно хранить любые символы. Символьные данные хранятся как строки символов, где байтовые значения соответствуют схеме кодирования символов (обычно называемой набором символов или кодовой страницей); набор символов базы данных устанавливается при создании базы данных и никогда не изменяется. Примерами наборов символов служат 7-битовый ASCII (американский стандартный код для обмена информацией), кодовая страница 500 набора символов EBCDIC (расширенный двоично-кодированный десятичный код обмена) или Japan Extended UNIX. ORACLE поддерживает как однобайтовые, так и мультибайтовые схемы кодирования. Обратитесь к приложению E для дополнительной информации о средствах поддержки национальных языков (NLS) в ORACLE и о том, как поддерживаются различные схемы кодирования символов.

Так как ORACLE дополняет пробелами значения в столбцах CHAR и не дополняет пробелами значения в столбцах VARCHAR2, столбцы VARCHAR2 более экономны в смысле затрат памяти на хранение. По этой причине, при полном просмотре большой таблицы, содержащей столбцы VARCHAR2, необходимо прочитать меньше блоков, чем для аналогичной таблицы со столбцами CHAR. Если ваше приложение часто выполняет полные просмотры больших таблиц, содержащих символьные данные, вы можете улучшить производительность, выбрав для таких данных тип данных VARCHAR2 вместо CHAR.

Однако производительность - не единственный фактор, который необходимо рассматривать при выборе между этими типами данных. ORACLE применяет различные семантики при сравнении значений для каждого из этих типов данных. Вы можете предпочесть один тип другому, если ваше приложение чувствительно к различиям между этими семантиками. Например, если вы хотите, чтобы ORACLE игнорировал хвостовые пробелы при сравнении символьных значений, то вы должны хранить такие значения в столбцах CHAR. Для информации о семантиках сравнения для символьных типов данных обратитесь к документу ORACLE7 Server SQL Language Reference Manual.

Тип данных CHAR

Тип данных CHAR хранит строки ФИКСИРОВАННОЙ длины. При создании таблицы со столбцом CHAR для этого столбца задается длина (в байтах, а не в символах) от 1 до 255 (по умолчанию 1). Затем ORACLE гарантирует соблюдение следующих правил:

ORACLE сравнивает значения CHAR, используя ДОПОЛНЯЮЩУЮ СЕМАНТИКУ сравнения. Если сравниваемые значения имеют разную длину, то ORACLE дополняет более короткое значение пробелами до равной длины. Если два значения отличаются лишь числом хвостовых пробелов, то они считаются равными.

Тип данных VARCHAR2

Тип данных VARCHAR2 хранит символьные строки ПЕРЕМЕННОЙ длины. При создании таблицы со столбцом VARCHAR2 для этого столбца задается максимальная длина (в байтах, а не в символах) от 1 до 2000. Для каждой строки, значение столбца VARCHAR2 записывается как поле переменной длины (если входное значение превышает максимальную длину столбца, ORACLE возвращает ошибку). Например, предположим, что столбец объявлен с типом VARCHAR2 и максимальной длиной 50 символов. Если входное значение для этого столбца имеет длину 10 символов, то (в однобайтовом наборе символов) значение столбца в строке будет иметь длину 10 символов (10 байт), а не 50.

ORACLE сравнивает значения VARCHAR2, используя НЕДОПОЛНЯЮЩУЮ СЕМАНТИКУ сравнения. Два значения считаются равными лишь тогда, когда они состоят из одних и тех же символов и имеют одинаковую длину.

Тип данных VARCHAR

Тип данных VARCHAR в настоящее время является синонимом типа данных VARCHAR2. Однако в будущей версии ORACLE тип данных VARCHAR будет хранить строки символов переменной длины с иной семантикой сравнения. Поэтому используйте тип данных VARCHAR2 для символьных строк переменной длины.

Длины столбцов для символьных типов данных

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

Тип данных NUMBER

Тип данных NUMBER используется для хранения нуля и положительных или отрицательных чисел с фиксированной и плавающей точкой. Для этого типа данных гарантируется переносимость между любыми операционными системами, которые поддерживает ORACLE, с точностью до 38 цифр. Вы можете хранить положительные и отрицательные числа в интервале от 1 x 10**-130 до 9.99..9 x 10**125 (с точностью до 38 значащих цифр), а также ноль.

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

имя_столбца NUMBER  

или можно указать ТОЧНОСТЬ (общее число цифр) и МАСШТАБ (число цифр справа от десятичной точки):

имя_столбца NUMBER (точность, масштаб)  

Если точность не указана, столбец хранит значения так, как они задаются. Если не указан масштаб, он считается нулевым. Масштаб может принимать значения от -84 до 127.

Хотя это и не обязательно, при задании числовых полей рекомендуется явно указывать точность и масштаб; это обеспечивает возможность дополнительной проверки данных на входе. На табл.3-1 приведены примеры хранения данных при использовании различных показателей масштаба.

Табл.3-1

Влияние показателя масштаба на хранение числовых данных
Входные данные
Тип столбца
Хранится как
7,456,123.89
NUMBER(*,1)
7456123.9
7,456,123.89
NUMBER(9)
7456123
7,456,123.89
NUMBER(9,2)
7456123.89
7,456,123.89
NUMBER(9,1)
7456123.9
7,456,123.89
NUMBER(6)
ошибка: превышена точность
7,456,123.89
NUMBER(7,-2)
7456100

Тип данных DATE

Тип данных DATE хранит значения в виде точек времени (т.е. дату и время). Тип данных DATE запоминает год (включая век), месяц, день, часы, минуты и секунды. ORACLE может хранить даты в диапазоне от 1 января 4712 года до н.э. до 31 декабря 4712 года нашей эры. Если в маске формата не указано BC (до н.э.), предполагается по умолчанию наша эра (AD).

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

Стандартный формат даты ORACLE для ввода и вывода имеет вид DD-MON-YY, например:

'13-NOV-92'  

Этот умалчиваемый формат даты можно изменить для инстанции с помощью параметра NLS_DATE_FORMAT. Его можно также изменить на время сессии пользователя с помощью предложения ALTER SESSION. Для ввода дат в формате, отличном от текущего умалчиваемого формата даты, используйте функцию TO_DATE с маской формата, например:

TO_DATE ('November 13, 1992', 'Month DD, YYYY')  

Если используется стандартный формат DD-MON-YY, то YY указывает год в 20-м веке (например, 31-DEC-92 означает 31 декабря 1992 г.). Если вы хотите задавать годы в другом веке, используйте другую маску формата, как показано выше.

Время хранится в 24-часовом формате HH:MM:SS. Если не введено значение времени, по умолчанию предполагается полночь (12:00:00 A.M.). Если вводится только порция, содержащая время, то за дату принимается первый день текущего месяца. Для того, чтобы ввести в дату время, необходимо это указать в маске формата функции TO_DATE, например:

INSERT INTO birthdays (bname, bday) VALUES
   ('ANNIE',TO_DATE('13-NOV-92 10:56 AM','DD-MON-YY HH:MI AM')); 

Для сравнения дат, содержащих время, используйте функцию SQL TRUNC, если вы хотите проигнорировать компоненту времени. Используйте функцию SQL SYSDATE, чтобы получить текущие системные дату и время. С помощью параметра FIXED_DATE можно установить SYSDATE как константу; это может быть полезно при отладке.

Использование юлианских дат

Юлианские даты позволяют датировать события от общей точки. (Эта точка принимается за 01-01-4712 г. до н.э., так что сегодняшние даты лежат где-то в пределах 2.4 миллиона дней.) Юлианская дата по определению нецелая, ее дробная часть составляет часть дня. ORACLE использует упрощенный подход, в котором используются целые числа. Юлианские даты могут вычисляться и интерпретироваться по-разному; метод, используемый в ORACLE, представляет дату в виде семизначного числа (для наиболее часто используемых дат); например, 8 апреля 1991 года будет представлено в виде 2448355.

Для преобразования дат в даты юлианского календаря в функциях преобразования даты (TO_DATE, TO_CHAR) может быть использована маска формата "J". Например следующий запрос возвращает все даты в юлианском формате:

SELECT TO_CHAR (hiredate, 'J') FROM emp;  

Чтобы использовать юлианские даты в вычислениях, необходимо использовать также функцию TO_NUMBER. Для ввода юлианских дат можно использовать функцию TO_DATE:

INSERT INTO emp (hiredate) VALUES (TO_DATE(2448921, 'J'));   

Арифметика дат

Арифметика дат ORACLE учитывает аномалии исторически применяемых календарей. Например, при переходе с юлианского календаря на грегорианский календарь, 15 октября 1582 года, были потеряны предыдущие 10 дней (с 05 по 14 октября). Кроме того, год 0 не существует.

Пропущенные даты могут быть введены в базу данных, но они игнорируются в арифметике дат и рассматриваются как следующая "реальная" дата. Например, следующим днем за 04 октября 1582 будет 15 октября 1582, а следующим днем за 05 октября 1582 будет 16 октября 1582.

Замечание: Это обсуждение арифметики дат применимо не ко всем национальным стандартам дат (например, некоторым в Азии).

Тип данных LONG

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

Использование данных LONG

Тип данных LONG используется в словаре данных для хранения текста определений обзоров. Вы можете использовать столбцы, определенные как LONG, в списках SELECT, фразах SET предложений UPDATE и фразах VALUES предложений INSERT.

Ограничения на данные типа LONG и LONG RAW

Хотя столбцы типа LONG (и LONG RAW; см. ниже) находят много различных применений, на их использование накладываются некоторые ограничения:

Проектируя таблицы, содержащие данные LONG или LONG RAW, помещайте каждый столбец LONG или LONG RAW в особую таблицу, отдельно от любых других связанным с ними данных, вместо того чтобы хранить столбец LONG или LONG RAW в общей таблице с другими данными. После этого вы можете связать обе таблицы ограничением ссылочной целостности. Такой проект позволит предложениям SQL, использующим лишь другие ассоциированные данные, избежать сканирования по данным LONG или LONG RAW.

Пример

Чтобы сохранить информацию о журнальных статьях, включая текст каждой статьи, создайте две таблицы:

CREATE TABLE article_header (id           NUMBER  
                                          PRIMARY KEY,
                             title        VARCHAR2(200),  
                             first_author VARCHAR2(30), 
                             journal      VARCHAR2(50),
                             pub_date     DATE)  
CREATE TABLE article_text   (id           NUMBER  
                                          REFERENCES
                                          article_header,  
                             text         LONG)  

Таблица ARTICLE_TEXT хранит только текст каждой статьи. Таблица ARTICLE_HEADER хранит всю остальную информацию о статье, включая ее заголовок, первого автора, название журнала и дату публикации. Обе таблицы связаны ограничением ссылочной целостности по столбцу ID в каждой таблице.

Этот проект позволяет предложениям SQL опрашивать данные, отличные от текстов статей, не читая самих текстов. Например, если вы хотите выбрать всех первых авторов, публиковавшихся в журнале "Nature" в течение июля месяца 1991 года, вы можете выдать следующий запрос по таблице ARTICLE_HEADER:

SELECT first_author
  FROM article_header
  WHERE journal = 'NATURE'
       AND TO_CHAR(pub_date,'MM YYYY') = '07 1991'  

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

Типы данных RAW и LONG RAW

Типы данных RAW и LONG RAW используются для данных, которые не должны ни интерпретироваться ORACLE, ни преобразовываться при передаче данных между различными системами. Эти типы данных предназначены для двоичных данных или байтовых строк. Например, LONG RAW можно использовать для хранения графики, звука, документов или массивов двоичных данных; их интерпретация зависит от их использования.

RAW эквивалентен VARCHAR2, а LONG RAW эквивалентен LONG, с тем исключением, что SQL*Net (который соединяет пользовательские сессии с инстанцией) и утилиты экспорта и импорта не выполняют преобразований при передаче данных RAW или LONG RAW. Напротив, SQL*Net и импорт/экспорт автоматически конвертируют данные CHAR, VARCHAR2 и LONG между набором символов базы данных и набором символов сессии пользователя (установленным параметром NLS_LANGUAGE или командой ALTER SESSION), если эти наборы символов различны.

Когда ORACLE автоматически преобразует данные RAW или LONG RAW в тип данных CHAR или из него (как в случае, когда данные RAW вводятся как литерал в предложении INSERT), эти данные рассматриваются как шестнадцатеричные цифры, каждая из которых представляет полубайт (четыре бита). Например, один байт данных RAW с битовым представлением 11001011 вводится и отображается как 'CB'.

Данные LONG RAW не могут индексироваться, однако данные RAW можно индексировать.

ROWID'ы и тип данных ROWID

Каждой строке некластеризованной таблицы в базе данных ORACLE назначается уникальный ROWID, соответствующий физическому адресу данной строки (начального куска строки, если строка хранится как

несколько кусков, связанных в цепочку). В случае кластеризованных таблиц, строки разных таблиц, если они хранятся в одном и том же блоке данных, могут иметь одинаковый ROWID.

Каждая таблица в базе данных ORACLE внутренне имеет ПСЕВДОСТОЛБЕЦ с именем ROWID; этот псевдостолбец не виден при выдаче структуры таблицы с помощью предложения SELECT * FROM ... или предложения DESCRIBE в SQL*Plus. Однако адрес каждой строки можно извлечь запросом SQL, используя ключевое слово ROWID как имя столбца, например:

SELECT ROWID, ename FROM emp;  

ROWID'ы используют двоичное представление физического адреса для каждой выбираемой строки. При запросах из SQL*Plus или SQL*DBA это двоичное представление преобразуется в шестнадцатеричное представление VARCHAR2, и запрос, показанный выше, мог бы возвратить следующую информацию строк:

ROWID              ENAME 
------------------ ----------
00000DD5.0000.0001 SMITH 
00000DD5.0001.0001 ALLEN
00000DD5.0002.0001 WARD  

Как показано выше, VARCHAR2/шестнадцатеричное представление ROWID разделяется на три компоненты: блок.строка.файл.

ROWID, назначенный строке, остается неизменным до тех пор, пока строка не будет экспортирована и вновь импортирована (с помощью утилит IMPORT и EXPORT). Когда строка удаляется (и соответствующая транзакция подтверждена), ROWID, ассоциированный с удаленной строкой, может быть назначен строке, вставляемой в последующей транзакции.

Нельзя устанавливать значение псевдостолбца ROWID в предложениях INSERT или UPDATE. Значения ROWID в псевдостолбце ROWID внутренне используются ORACLE в разнообразных операциях (см. следующую секцию). Хотя к значениям псевдостолбца ROWID можно обращаться как к другим столбцам таблицы (в списках SELECT и фразах WHERE), эти значения не хранятся в базе данных и не являются данными базы данных.

ROWID'ы и базы данных не-ORACLE

Приложения базы данных ORACLE можно выполнять на серверах баз данных, отличных от ORACLE, используя SQL*Connect или Oracle Open Gateway. В таких случаях двоичный формат значений ROWID изменяется в соответствии с характеристиками системы не-ORACLE. Более того, стандартная трансляция значений ROWID в формат VARCHAR2/шестнадцатеричный недоступна. Программы могут по-прежнему использовать тип данных ROWID; однако они должны применять нестандартную трансляцию в шестнадцатеричный формат, используя до 256 байт. Обратитесь к соответствующему

руководству по OCI или прекомпилятору за дополнительными подробностями об использовании значений ROWID в сочетании с системами, отличными от ORACLE.

Как используются ROWID'ы

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

Некоторые характеристики ROWID'ов могут также использоваться разработчиками приложений: * ROWID'ы дают самый быстрый доступ к конкретным строкам.

Прежде чем использовать ROWID'ы в предложениях DML, они должны быть проверены и гарантированы от изменений; иными словами, необходимые строки должны быть заблокированы, чтобы их нельзя было удалить. Попытка обращения к данным с некорректным значением ROWID приведет либо к тому, что строка не будет возвращена, либо к ошибке 1410 (неверный ROWID).

Вы можете также создавать таблицы со столбцами, определенными с типом данных ROWID; например, вы определяете таблицу исключений со столбцом типа данных ROWID, чтобы запоминать ROWID'ы тех строк базы данных, которые нарушают ограничения целостности. Столбцы, определенные с типом данных ROWID, ведут себя как обычные столбцы; их значения можно обновлять, и т.п. Все значения в столбце типа данных ROWID занимают шесть байт.

Примеры использования значений ROWID

Используя ROWID с некоторыми групповыми функциями, вы можете увидеть, как данные внутренне хранятся в базе данных ORACLE.

Функцию SUBSTR можно использовать, чтобы разбить значение ROWID на три его компоненты (файл, блок и строку). Например, запрос

SELECT ROWID, SUBSTR(ROWID,15,4) "FILE",
       SUBSTR(ROWID,1,8) "BLOCK",
       SUBSTR(ROWID,10,4) "ROW"
       FROM emp;   

мог бы возвратить следующие данные:

ROWID              FILE BLOCK    ROW
------------------ ---- -------- ---
00000DD5.0000.0001 0001 00000DD5 0000
00000DD5.0001.0001 0001 00000DD5 0001
00000DD5.0002.0001 0001 00000DD5 0002  

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

SELECT COUNT(DISTINCT(SUBSTR(ROWID,15,4))) "FILES" FROM таблица;  

результаты этого запроса могут быть следующими:

FILES
-------
2
предыдущая часть | содержание | следующая часть

Дополнительную информацию Вы можете получить в компании Interface Ltd.

Отправить ссылку на страницу по e-mail
Обсудить на форуме Oracle


Interface Ltd.
Тel/Fax: +7(095) 105-0049 (многоканальный)
Отправить E-Mail
http://www.interface.ru
Ваши замечания и предложения отправляйте автору
По техническим вопросам обращайтесь к вебмастеру
Документ опубликован: 11.03.01