Разработка при помощи Apache Derby -- тройной выигрыш: Разработка баз данных при помощи Apache Derby, Часть 2

Схемы

Эта статья, фокусируя внимание на роли разработчика баз данных, описывает основные типы данных, которые можно использовать для хранения данных в базе Apache Derby; вам предстоит применить их на практике, чтобы создать в Apache Derby простую схему с двумя таблицами для воображаемого магазина.

Роберт Бруннер , ученый-исследователь NCSA, старший преподаватель астрономии, Университет штата Иллинойс, г. Урбана-Шампейн

Роберт Дж.  Бруннер (Robert J. Brunner)Роберт Дж. Бруннер (Robert J. Brunner) занимается научными исследованиями в Национальном центре по приложениям для суперкомпьютеров и является старшим преподавателем астрономии в университете штата Иллинойс, город Урбана-Шампейн. Автор нескольких книг и множества статей и практических руководств на различные темы.



18.04.2006

Основные понятия систем управления реляционными базами данных

Прежде, чем начать разрабатывать приложения баз данных, вам необходимо усвоить основные понятия. В этом разделе представлены типы данных, доступные для использования в Apache Derby, и правила, которые влияют на ваши возможности по проектированию и созданию эффективных приложений базы данных Derby.

Реляционные базы данных содержат данные. Это могут быть данные различных типов, например, числа, символы или даты. Данные в базе данных организуются в логические структуры, которые называются таблицами. Таблица похожа на электронную таблицу, поскольку содержит строки данных. Каждая строка содержит несколько столбцов. В столбце хранятся данные определенного типа, например, целые значения или строки символов. В большинстве случаев база данных состоит более чем из одной таблицы. Чтобы связать таблицы друг с другом, разработчик базы данных использует естественные (или искусственные) связи между таблицами. В электронной таблице вы можете связать строки в различных листах по значениям в ячейках. Эта же идея используется в реляционных базах данных, а столбец, используемый для создания связи, называется первичным ключом.

Чтобы лучше представлять себе назначение таблицы или отдельного столбца, следует выбирать для них соответствующие имена. Соглашение об используемых именах может отличаться в различных базах данных. В системе баз данных Apache Derby отдельные имена:

  • Не чувствительны к регистру;
  • Имеют длину не более 128 символов;
  • Должны начинаться с буквы;
  • Должны содержать только буквы в кодировке Unicode, символы подчеркивания и цифры в кодировке Unicode.

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

Стиль Derby

В этой серии статей используется особый стиль: все команды SQL представлены в верхнем регистре, а имена объектов используют "горбатый" регистр. В стиле "горбатый регистр" слова соединяются друг с другом, а первая буква каждого слова - за исключением первого слова - становится заглавной, например, aLongIdentifier. Поскольку в наших статьях эти два стиля используются вместе, команды SQL выглядят примерно так : SELECT aLongIdentifier FROM bigdog.dataTable ;.

Связанные таблицы часто группируются в схему. Схему можно сравнить с контейнером для всех определений родственной структуры в отдельной базе данных. Имя таблицы должно быть уникальным в пределах данной схемы. Таким образом, при использовании схем, вы можете иметь объекты с одинаковыми именами (например, таблицы) в различных схемах. В базе данных Apache Derby таблица всегда находится в схеме. Если схема не была задана явно, то Derby неявно использует встроенную схему apps. Другая встроенная схема, sys, используется для изоляции системных таблиц.

Имя схемы можно использовать для уточнения имени объекта. Для этого сначала пишется имя схемы, после которого следует точка, а затем имя таблицы. Например, bigdog.products описывает таблицу products в схеме bigdog. Без имени соответствующей схемы имя таблицы называется неуточненным, например, products. Если заданы и имя схемы, и имя таблицы, как в имени bigdog.products, имя считается полностью уточненным.

При абстрактном рассмотрении эти понятия базы данных могут показаться сложными, но на практике они довольно понятны. Например, представьте себе, что вы являетесь владельцем магазина, под названием Bigdog's Surf Shop, в котором продаются различные предметы, такие, как солнцезащитные очки, рубашки и т.д. Если вы хотите, чтобы магазин приносил прибыль, вам следует внимательно следить за ассортиментом, чтобы можно было легко заказать дополнительный ассортимент или сменить поставщика для сокращения накладных расходов. Один из самых простых методов отслеживать эту информацию - это вести записи в табличном формате, как показано на рисунке 1.

Рисунок 1. Пример схемы для магазина Bigdog's Surf Shop
Пример схемы для магазина Bigdog's Surf Shop, показывающий таблицы Products и Vendors

По этому простому наглядному проекту вы можете легко перенести бизнес-логику в таблицы базы данных. У вас есть две таблицы, Products и Vendors, которые естественным образом связаны номером товара. Типы данных для столбцов в каждой таблице легко определить. Далее в этой статье речь пойдет о создании примера схемы для магазина Bigdog's Surf Shop -- она состоит из двух таблиц -- в базе данных Derby.


Работа с реляционной базой данных: структурированный язык запросов (Structured Query Language, SQL)

Тип SQL NULL

Прежде, чем вы приступите к созданию таблиц базы даных, вам необходимо знать, что делать, если для столбца не задано значение. Чтобы разобраться в этом моменте, представьте себе, что вас попросили заполнить Web-форму. Если вы оставите некоторые столбцы пустыми, то что будет внесено в базу данных? Нетрудно представить, что эта проблема могла бы быть весьма непростой, если бы вам нужно было отслеживать маркеры отсутствия значения. К счастью, в SQL имеется особое значение, NULL, которое показывает, что значение для столбца не задано.

Системы баз данных могут быть законченными фрагментами программного обеспечения, особенно в том случае, если они масштабируются для поддержки приложения корпоративного уровня. В результате можно ожидать, что каждая база данных имеет собственный интерфейс прикладного программирования (API), и АPI разных систем могут отличаться друг от друга. Когда только началась разработка баз данных, так все и выглядело; но, к счастью, многие разработчики пришли к соглашению о разработке стандартного языка для доступа и манипуляций с реляционными базами данных. Официально этот язык называется Structured Query Language (структурированный язык запросов), или SQL, произносится как sea-quill. Было выпущено несколько официальных версий стандарта, среди которых версия 1992 года, которая называется SQL-92, и версия 1999 года, SQL-99. База данных Apache Derby представляет собой почти полную реализацию стандарта SQL-92, поэтому приложения, разработанные при помощи Derby, можно легко перенести на другие системы баз данных.

SQL имеет два основных компонента: a Data Definition Language (язык определения данных, DDL) и Data Manipulation Language (язык управления данными, DML). Команды DDL используются для создания, изменения или удаления объектов (например, таблиц) базы данных. Команды DML используются для добавления, изменения, удаления или выбора данных из таблицы базы данных. Далее в этой статье вы найдете введение в основы DDL-компонентов языка SQL. В следующих статьях мы перейдем к рассмотрению DML-команд и более сложных команд DDL.

Типы данных SQL

SQL, который по сути является языком программирования, имеет разветвленную иерархию типов данных. Сохранение этих типов данных - одна из наиболее важных задач базы данных. Поскольку базы данных стали более эффективными, иерархия типов разрослась и стала более сложной. Но большинству простых баз данных не нужен полный диапазон разрешенных типов, и зачастую им нужно хранить только числовые и символьные данные, а также информацию о времени и дате. Для простоты в таблицах 1, 2, 3 и 4 представлены основные типы данных SQL, реализованные в Derby.

Как показано в таблице 1, Derby обеспечивает поддержку трех различных типов целочисленных данных. Эти типы различаются диапазоном целых значений, которые они могут хранить, а, значит, и объемом дискового пространства, который они занимают в базе данных. При проектировании базы данных всегда следует пытаться уменьшить объем занимаемого ею дискового пространства. Как правило, таблицы меньшего размера обеспечивают более высокую производительность, но при этом должна быть возможность хранить данные в обобщающей таблице. Для записи, 231 эквивалентно 2,147,483,648, а 263 эквивалентно 9,223,372,036,854,775,808, поэтому использование этих типов данных позволяет хранить очень большие целые числа!

Таблица 1. Основные целочисленные типы данных (integer)' в Derby
Тип данныхМинимальное значениеМаксимальное значениеПримерОписание
SMALLINT-32768 (-215)32767 (215 - 1)itemNumber SMALLINTдвухразрядное представление integer
INT-231231 - 1itemNumber INTчетырехразрядное представление integer
BIGINT-263263 - 1itemNumber BIGINTвосьмиразрядное представление integer

Большинство числовых данных невозможно представить в виде целого числа. Derby обеспечивает поддержку действительных чисел в нескольких форматах: представление с плавающей точкой floating-point single-precision, floating-point double-precision и точное представление decimal, как показано в таблице 2.

Таблица 2. Основные числовые типы данных в Derby
Тип данныхМинимальное значениеМаксимальное значениеПримерОписание
REAL-3.402x10+383.402x10+38price REALIEEE число с плавающей точкой (4 разряда)
DOUBLE-1.79769x10+3081.79769x10+308price DOUBLEIEEE число с плавающей точкой (8 разрядов)
DECIMAL31 (максимальная точность)price DECIMAL(5,2)Точное представление decimal

Если вы никогда не встречались с типом данных exact precision, то различие между типами decimal и floating-point может оказаться трудным для понимания. Различие заключается в том, что типы данных floating-point, которые используются в компьютерах, не могут отобразить любое действительное число. Это может показаться странным, но вспомните, что существует бесконечно много различных действительных значений. Большинство действительных чисел невозможно сохранить в нескольких разрядах памяти. Для некоторых приложений такая потеря точности является приемлемой. Однако в большинстве случаев это недопустимо. Например, финансовое приложение не может позволить себе терять деньги только потому, что какое-либо число невозможно сохранить в памяти компьютера.

Решение проблемы заключается в использовании типа данных DECIMAL, который позволяет управлять общим количеством цифр, сохраняемых компьютером (точность) и числом цифр после десятичной запятой (масштаб). Для создания типа данных decimal нужно определить точность и, по желанию, масштаб сохраняемых данных. Дисковое пространство, необходимое для хранения типа данных DECIMAL, потенциально намного больше дискового пространства для хранения типа данных floating-point. Следовательно, следует с осторожностью пользоваться этим типом, в противном случае может понизиться производительность приложения. По умолчанию масштаб типа DECIMAL равен 0, это означает, что тип данных DECIMAL имитирует тип integer.

Существует несколько синонимов числовых типов. Например, название типа данных DECIMAL можно сократить до DEC; допустимо также NUMERIC. Тип DOUBLE может называться также DOUBLE PRECISION, хотя не совсем ясно, из каких соображений кто-либо мог бы захотеть вводить лишнее слово каждый раз, когда возникнет необходимость в числе типа double-precision. Чаще употребляется синоним FLOAT, имеющий произвольную точность, которая задается при объявлении типа данных как FLOAT(val). Точность должна быть положительным числом, не превышающим 53; в противном случае вы получите сообщение об ошибке. Если задано значение точности 23 или меньше, то тип FLOAT(val) эквивалентен типу REAL; если точность лежит в диапазоне от 24 до 53, тип FLOAT(val) эквивалентен типу DOUBLE.

Помимо числового типа существует еще один распространенный тип данных, которые можно хранить в базе данных - это символьные данные. Примеры символьных данных - описание объекта, имя лица или информация об адресе. Derby предоставляет два простых способа хранения символьных данных: с помощью типа данных CHAR и типа VARCHAR, которые описаны в табл. 3. Для обоих типов вы можете задать параметр length, который по умолчанию равен 1, если значение не задано. Между этими двумя символьными типами данных существует два главных отличия. Во-первых, тип CHAR имеет максимальную длину 254 символа, тогда как тип VARCHAR может содержать до 32,672 символов. Второе отличие более тонкое: тип CHAR всегда имеет заданную длину. Если задано недостаточное количество символов, то для заполнения используются дополнительные пробелы. В случае VARCHAR количество символов может изменяться, принудительное заполнение не выполняется.

Таблица 3. Основные символьные типы данных в Derby
Тип данныхМаксимальная длинаПримерОписание
CHAR254description CHAR(128)Строка символов постоянной длины
VARCHAR32,672description VARCHAR(128)Строка символов переменной длины

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

Последний простой тип данных, который Derby предоставляет для хранения даты и времени, подробно описывается в таблице 4. Тип данных TIME хранит часы, минуты и секунды в 24-часовом формате (HH:MM:SS). Тип данных DATE сохраняет месяц, день и год, которые могут быть заданы в нескольких различных форматах, в том числе:

  • гггг-мм-дд
  • мм/дд/гггг
  • дд.мм.гггг
Таблица 4. Основные типы данных для времени и даты в Derby
Тип данныхМинимальное значениеМаксимальное значениеПримерОписание
TIME00:00:0024:00:00start TIMEПредставление времени (с точностью до секунд)
DATE0001-01-019999-12-31stockDate DATEПредставление даты (с точностью до дня)

Derby также предоставляет тип данных TIMESTAMP (временная метка), который объединяет типы данных TIME и DATE в один тип, предназначенный для отметки точного момента времени.


Создание таблицы в Derby

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

Листинг 1. Синтаксис выражения CREATE TABLE для Apache Derby
--  Comment describing the purpose and layout of the table

CREATE TABLE [schemaName.]tableName (
    { <columnDefinition> | <tableLevelConstraint>  } [,
        { <columnDefinition> | <tableLevelConstraint>  }
    ]*
) ;

На первый взгляд этот синтаксис может показаться непонятным. Но если вы поняли основы, пользоваться им не сложно; кроме того, вы должны знать формальный синтаксис, если хотите в совершенстве владеть Derby. В квадратные скобки ([ и ]) заключаются необязательные параметры. Как видно из описания формального синтаксиса, имя схемы является необязательным, как и любые описания столбцов или ограничения уровня таблицы после обязательного первого (вряд ли имеет смысл создать таблицу без столбцов).

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

Звездочка (*) после последней закрывающей квадратной скобки показывает, что в скобки можно заключить более одного объекта. Это подразумевает, что таблица должна иметь одно или более ограничений на уровне столбца или таблицы. Вертикальная линия (|) показывает условие или/или. В нашем примере синтаксиса следует определить либо новое ограничение на уровне столбца, либо новое ограничение на уровне таблицы. Группа фигурных скобок ({ и }) связывает объекты друг с другом, а в круглые скобки (( и )) заключены обязательные элементы. И, наконец, точка с запятой (;) показывает завершение предложения SQL.

Применять эти правила на практике несложно. В листинге 2 демонстрируется, как создать таблицы, которые были показаны на рисунке 1, при помощи инструмента ij, который поставляется с Derby.

Листинг 2. Создание таблицы в Apache Derby
rb$ java org.apache.derby.tools.ij
ij version 10.1
ij> connect 'jdbc:derby:test;create=true' ;
ij> CREATE TABLE bigdog.products (
itemNumber INT NOT NULL,
price DECIMAL(5, 2),
stockDate DATE,
description VARCHAR(128)
) ;
0 rows inserted/updated/deleted
ij> CREATE TABLE bigdog.vendors (
itemNumber INT NOT NULL,
vendorNumber INT NOT NULL,
vendorName CHAR(64)
) ;
0 rows inserted/updated/deleted
ij> exit ;

Самый простой способ работы с базой данных Derby - это использование инструмента ij , о котором говорилось в первой статье данного цикла, "Разработка при помощи Apache Derby -- тройной выигрыш: введение в Apache Derby" (сайт developerWorks, февраль 2006 г.). Если вы по порядку выполняете все действия, показанные в листинге 2, то сначала создаете новую базу данных с именем test. При выполнении предложения connect вы можете получить предупреждающее сообщение в том случае, если база данных test уже существует. Это предупреждение можно игнорировать. Далее, вы неявно создаете новую схему с именем bigdog и явно создаете две новые таблицы -- products и vendors -- которые сохраняются в схеме bigdog. Создание схемы происходит неявным образом, потому что предложение CREATE SCHEMA не выполняется.

В таблице products четыре столбца: itemNumber, price, stockDate и description. Столбец itemNumber содержит уникальный идентификатор для каждого элемента (или записи) и имеет присоединенное ограничение на уровне столбца, которое требует, чтобы в столбец всегда вводилось корректное значение (NOT NULL). Без этого требования столбцу itemNumber не гарантируется уникальность, поскольку значение NULL может быть задано для нескольких столбцов. Столбец price создается с типом данных DECIMAL, точностью 5 и масштабом 2. Это означает, что максимальная цена любого товара равна $999.99. Последние два столбца достаточно просты: столбец stockDate сохраняется как Date, а столбец description сохраняется как строка данных с максимальной длиной 128, которая уменьшается до длины вводимых данных.

Таблица vendors имеет три столбца: itemNumber, vendorNumber и vendorName. В этом случае оба столбца, itemNumber и vendorNumber, имеют присоединенное ограничение на уровне столбца (NOT NULL). Кроме того, столбец vendorName сохраняется как строка символов с максимальной длиной 64. Поскольку столбец vendorName сохраняется с типом данных CHAR, то всегда резервируется место для 64 символов.

Создав различные объекты, вы можете поинтересоваться, существует ли способ просмотреть, какие объекты хранятся в базе данных. Да, можно при помощи инструмента dblook. После запуска этого инструмента, как показано в листинге 3, на экран выводится подробный список объектов, которые были созданы в конкретной базе данных.

Листинг 3. Просмотр схемы при помощи инструмента dblook
rb$ java org.apache.derby.tools.dblook -d jdbc:derby:test
-- Timestamp: 2006-03-04 10:52:34.056
-- Source database is: test
-- Connection URL is: jdbc:derby:test
-- appendLogs: false

-- ----------------------------------------------
-- DDL Statements for schemas
-- ----------------------------------------------

CREATE SCHEMA "BIGDOG";

-- ----------------------------------------------
-- DDL Statements for tables
-- ----------------------------------------------
CREATE TABLE "BIGDOG"."PRODUCTS" (
    "ITEMNUMBER" INTEGER NOT NULL, 
    "PRICE" DECIMAL(5,2), 
    "STOCKDATE" DATE, 
    "DESCRIPTION" VARCHAR(128));

CREATE TABLE "BIGDOG"."VENDORS" (
    "ITEMNUMBER" INTEGER NOT NULL, 
    "VENDORNUMBER" INTEGER NOT NULL, 
    "VENDORNAME" CHAR(64));

Инструмент dblook - это еще один класс Java, который позволяет без лишних сложностей отобразить в консоли содержание базы данных. Этот инструмент запускается из командной строки, так же, как и любая Java-программа; единственное дополнение - это использование аргумента -d jdbc:derby:test , определяющего базу данных, которую должен запросить инструмент dblook. Если вы можете запустить инструмент ij, то файлы класса dblook уже указаны в переменной CLASSPATH. Если нет, вернитесь к первой статье этого цикла и ознакомьтесь с подробными инструкциями по правильной настройке переменной CLASSPATH. Как показывает вывод инструмента dblook, база данных test включает схему bigdog, которая, в свою очередь, содержит таблицы products и vendors. Кроме того, приводится подробное описание различных столбцов этих двух таблиц.


Удаление таблицы в Derby

В мире нет ничего совершенного. Что делать, если вы неправильно создали таблицу или если таблица больше не нужна? Ответ прост - удалить таблицу из базы данных, и, если нужно, создать вместо нее другую. Удалить таблицу не сложно, но при этом вам, безусловно, следует быть очень внимательным - при удалении не появляется диалоговое окно с вопросом, уверены ли вы в том, что хотите продолжить!

Полный синтаксис удаления таблицы из базы данных:

DROP TABLE [schemaName.]tableName ;

Синтаксис несложен: вы вводите полное имя и точку с запятой в конце команды SQL DROP TABLE, и все кончено. Процесс удаления демонстрируется на вновь созданной временной таблице в листинге 4.

Листинг 4. Удаление таблицы из базы данных Derby
rb$ java org.apache.derby.tools.ij
ij version 10.1
ij> connect 'jdbc:derby:test' ;
ij> CREATE TABLE temp ( aColumn INT ) ;
0 rows inserted/updated/deleted
ij> DROP TABLE temp ;
0 rows inserted/updated/deleted
ij> exit ;

Заключение

Вы твердо стоите на пути к овладению базой данных Apache Derby. Теперь вы усвоили основные понятия баз данных, включая схемы, таблицы и столбцы; наглядно изучили эти понятия на примере воображаемого предприятия под названием Bigdog's Surf Shop. Чтобы работать с такой базой данных, как Derby, как вы знаете, необходимо изучить язык SQL, стандартный язык взаимодействия с базами данных. В этой статье рассматриваются основные типы данных, которые можно использовать для хранения данных в базе данных Derby. Изучая эти понятия, вы научились создавать и удалять таблицы при помощи Derby, а также использовать инструмент dblook для создания дампа содержимого схемы базы данных.

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Information Management
ArticleID=172045
ArticleTitle=Разработка при помощи Apache Derby -- тройной выигрыш: Разработка баз данных при помощи Apache Derby, Часть 2
publish-date=04182006