В настоящем разделе будет рассмотрена первая профессиональная задача проектировщика базы данных по созданию
В рамках концепции
Таким образом, SQL. Выполнение этой последовательности команд создает конкретную базу данных и ее объекты.
Одной из основных задач проектировщика данных при создании
Элементарной подзадачей является создание таблицы базы данных. Таблицы в реляционных СУБД1 состоят из одной или более колонок или полей. Колонки представляют собой поименованные ячейки в записи, которые содержат значения. Колонки определяются посредством спецификации, которая определяет формат колонки и ее характеристики, задаваемые с помощью ограничений. Определение таблицы задается командой CREATE TABLE.
С точки зрения
CREATE TABLE для каждой СУБД приводится в соответствующем документе с названием типа "Справочное руководство по SQL для СУБДѕ".
Как указывалось выше, первый шаг в построении CREATE TABLE, которые будут использоваться далее для добавления колонок и других деталей.
Далее проектировщик базы данных формирует список всех пользователей каждой таблицы. При этом выделяются так называемые владельцы таблицы, т.е. пользователи, которые имеют все права доступа к таблице. Этот список используется на завершающем этапе проектирования
Когда проектировщик заканчивает обработку всех отношений
Пример. Для нашего учебного примера результат решения задачи настоящего пункта может иметь следующий вид:
CREATE TABLE DEPARTAMENT имя таблицы ( ); CREATE TABLE EMPLOYEE имя таблицы ( ); CREATE TABLE PROJECT имя таблицы ( );
Следующим шагом проектировщика базы данных является определение колонок для CREATE TABLE.
Сначала рассмотрим задачу добавления колонок. Колонка должна иметь имя. Имена атрибутов соответствующих отношений логической модели преобразуются в имена колонок в соответствии с правилами именования объектов, принятых в конкретной СУБД. Обычно, как указывалось выше, это ограничение на длину имени и использование в имени специальных символов. Например, в некоторых СУБД допускается использовать знак доллара в имени, однако этот знак обычно не распознается в командах выборки данных - SELECT.
Имеется еще одна проблема в именовании колонок: имена колонок должны интерпретироваться пользователем однозначно. Например, если проектировщик базы данных назначит для фамилии сотрудника короткое имя LN, то, наверное, потребуется комментарий, в котором необходимо указать, что это фамилия, а не линия (например, линия производства). Если невозможно по каким-то причинам применять длинные имена полей, то следует использовать словарь данных для интерпретации введенных аббревиатур.
При назначении имен колонок проектировщик базы данных продолжает формировать стандартный список имен колонок и их сокращений в словаре данных. Он также должен выполнить проверку списка имен в словаре данных, чтобы избежать конфликтов имен в базе данных в целом.
Пример. Продолжим работу с учебным примером. После именования колонок получим следующее:
CREATE TABLE DEPARTAMENT ( DEPNO, имя колонки DNAME, LOC, MANAGER, PHONE, ); CREATE TABLE EMPLOYEE ( EMPNO, ENAME, LNAME, DEPNO, SSECNO, PROJNO, JOB, AGE, HIREDATE, SAL, COMM, FINE, ); CREATE TABLE PROJECT ( PROJNO, PNAME, BUDGET, );
После идентификации колонок необходимо задать их тип в соответствии с допустимыми для данной СУБД типами данных. Эта задача упрощается, если в отношениях логической модели определены домены атрибутов. Некоторые из доменов могут быть определены уже в терминах СУБД. Для таких атрибутов практически ничего делать не нужно. Определение домена в терминах типа данных СУБД нужно просто перенести в DEC (9,2), а из контекста предметной области следует, что в этой колонке будет накапливаться итоговая сумма расходов за год, то может быть целесообразным определить тип как DEC (15,2), чтобы избежать возможного переполнения при работе приложений базы данных.
Если домен определен не в терминах СУБД, проектировщик базы данных должен преобразовать его в подходящий тип данных. При выполнении таких преобразования следует учитывать ряд факторов.
varchar (3), которая содержит код, чье значение изменяется в интервале от '10A' ' до '99Z', то целесообразно с точки зрения хранения изменить тип этой переменной на char (3). Это объясняется тем, что тип varchar при физическом хранении занимает на байт-два больше, чем тип char при одной и той же объявленной длине.DEC. Он обрабатывается процессором быстрее, чем тип FLOAT. Исключение составляют данные для научных расчетов, где представление чисел в экспоненциальной форме бывает необходимо.INT и SMALLINT исключительно для счетчиков.LONG VARCHAR без лишней надобности. Обычно колонки такого типа хранятся на отдельном экстенте жесткого диска, причем не в той области диска, где хранятся остальные данные таблицы.CHAR для представления числовых данных. Во-первых, может потребоваться дополнительная проверка, а во-вторых, могут возникнуть проблемы при сортировке таких колонок, поскольку число, заданное строкой '11', будет находиться выше, чем число, заданное строкой '9', при упорядочивании по возрастанию.DATE и TIME только для хранения хронологических данных.DATETIME исключительно для целей управления данными.Пример. Продолжим изучение нашего примера. После определения типов колонок наши команды для создания таблиц будут выглядеть следующим образом:
CREATE TABLE DEPARTAMENT ( DEPNO integer, имя колонки, тип, длина DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), ); CREATE TABLE EMPLOYEE ( EMPNO integer, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), PROJNO char(8), JOB char(25), AGE date, HIREDATE date, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), ); CREATE TABLE PROJECT ( PROJNO char(8), PNAME char(25), BUDGET dec(9,2), );
После определения всех колонок и их типов следует перейти к идентификации первичных ключей таблицы. Согласно требованиям реляционной теории каждая строка таблицы (кортеж) должна иметь уникальный первичный ключ. Обычно хорошим кандидатом на первичный ключ таблицы является CREATE TABLE. Такое определение первичного ключа таблицы для многих таблиц не является окончательным. Переопределение первичного ключа может происходить на следующих этапах физического
Задание колонки как первичного ключа в контексте многих СУБД, в том числе и Oracle, считается ограничением на значение колонки (см. следующий подраздел).
PRIMARY KEY команды CREATE TABLE для спецификации первичного ключа таблицы. Атрибуты первичного ключа перечисляются через запятую и заключаются в круглые скобки. Если спецификация PRIMARY KEY не определяется, то считается, что таблица не имеет первичного ключа. При этом допускается дублирование строк в таблице.
Пример. Для нашего примера колонками первичного ключа могут быть назначены: колонка DEPNO в отношении DEPARTAMENT, колонка EMPNO в отношении EMPLOYEE, колонка PROJNO в отношении PROJECT.
CREATE TABLE DEPARTAMENT ( DEPNO integer, DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), PRIMARY KEY (DEPNO) определение первичного ключа ); CREATE TABLE EMPLOYEE ( EMPNO integer, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), PROJNO char(8), J OB char(25), AGE date, HIREDATE date, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), PRIMARY KEY (EMPNO) ); CREATE TABLE PROJECT ( PROJNO char(8), PNAME char(25), BUDGET dec(9,2), PRIMARY KEY (PROJNO) );
В СУБД Oracle можно задавать CREATE TABLE будет выглядеть так, как показано ниже для таблицы DEPARTAMENT:
CREATE TABLE DEPARTAMENT ( DEPNO integer primary key, определение первичного ключа DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), );
Когда вы определяете PRIMARY KEY при создании таблицы, многие реляционные СУБД требуют обязательного создания уникального
CREATE UNIQUE INDEX NDXDEPT ON DEPARTAMENT (DEPNO);
Предложение CREATE INDEX определяет имя индекса, предложение ON определяет имя таблицы и колонок, для которой и по которым строится индекс, ключевое слово UNIQUE указывает, что индексируемые значения колонок должны быть уникальными для таблицы, т.е. исключается дублирование значений в индексируемой колонке. Таблица должна быть уже создана, и должна содержать определения индексируемых столбцов. Спецификация UNIQUE опциональна, и вы можете также создавать и неуникальные индексы.
Следует помнить, что для многих СУБД целостность первичного ключа поддерживается заданием
Поэтому для завершения процедуры определения первичных ключей CREATE UNIQUE INDEX, как показано ниже:
CREATE UNIQUE INDEX NDXDEPT ON DEPARTAMENT (DEPNO); CREATE UNIQUE INDEX NDXEMPLOYEE ON EMPLOYEE(EMPNO); CREATE UNIQUE INDEX NDXPROJECT ON PROJECT(PROJNO);
Для диалекта SQL СУБД Oracle этого делать не нужно, т.к. она автоматически поддерживает целостность первичного ключа.
После выполнения вышеперечисленных действий задачу определения первичных ключей
При определении NOT NULL ограничением.
Предопределенное значение колонки, равное NULL, означает, что в данный конкретный момент для данной конкретной строки (экземпляра NULL -значения, т.к. пользователи могут иметь проблемы при использовании таких колонок. Примером этой проблемы может служить ситуация, в которой пользователю требуется выполнить соединение двух таблиц по колонкам, имеющим NULL -значения. При выполнении таких соединений любые строки, которые содержат NULL -значения в колонках соединения в любой из таблиц, не будут показаны в результирующей выборке для запроса. Подобная потеря данных может привести к тому, что пользователь получит неправильную выборку на запрос, особенно если ему необходимо видеть все строки хотя бы одной из таблиц.
Примечание. Одним из способов решения определенной выше проблемы является использование
внешних соединений .
При назначении NULL -значений колонкам проектировщику базы данных необходимо принимать во внимание следующие факторы.
NOT NULL, т.к. согласно реляционной теории значения колонок первичного ключа должны быть определены и уникальны для каждого кортежа.NOT NULL, поскольку дочерняя таблица зависит от родительской и внешний ключ родительской не может иметь NULL-значения. Это следует из того, что существование строки дочерней таблицы без соответствующей строки NULL -значений, чтобы показать, что для данной комбинации родительской и дочерних строк в этих таблицах связи нет.SET NULL должны определяться со спецификацией NULL.NOT NULL WITH DEFAULT для колонок с типами данных DATE или TIME, чтобы сохранять текущие даты и текущее время автоматически.NULL -значения только для тех колонок, которые действительно могут иметь неопределенные значения.NOT NULL WITH DEFAULT для всех колонок, которые не подпадают под перечисленные выше правила.Пример. Как можно увидеть ниже, проектировщик базы данных определил, что:
дата поступления служащего в организацию HIREDATEопределена со спецификациейNOT NULL WITH DEFAULT, которая означает, что если на вводе значение колонки не определено, то по умолчанию подставляется текущая дата;номер подразделения DEPNO, номер служащегоEMPNOи номер проектаPROJNOимеют спецификациюNOT NULLкак первичные ключи таблиц;для остальных полей базовых таблиц проектировщик базы данных принял решение разрешить наличие в нихNULL-значений.
CREATE TABLE DEPARTAMENT ( DEPNO integer NOT NULL, DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), PRIMARY KEY (DEPNO) определение первичного ключа ); CREATE TABLE EMPLOYEE ( EMPNO integer NOT NULL, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), PROJNO char(8), JOB char(25), AGE date, HIREDATE date NOT NULL WITH DEFAULT, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), PRIMARY KEY (EMPNO) ); CREATE TABLE PROJECT ( PROJNO char(8) NOT NULL, PNAME char(25), BUDGET dec(9,2), PRIMARY KEY (PROJNO) );
Отношения "многие-ко-многим", как уже упоминалось в предыдущих лекциях, не могут быть в подавляющем большинстве случаев непосредственно реализованы в реляционных базах данных без создания промежуточных таблиц, иначе называемых связывающими таблицами (
Алгоритм задачи разрешения взаимосвязи следующий:
Этот алгоритм решает задачу разрешения отношения "многие-ко-многим". Однако можно подумать об атрибутах (колонках), которые могут существовать у связи (ее представляет связывающая таблица). Такие колонки могут быть помещены в связывающую таблицу. Это могут быть колонки, общие для связываемых таблиц.
Рассмотрим пример. Используемая схема базы данных учебного примера не позволяет использовать одного служащего в нескольких проектах (реализовано отношение "много (служащих) к одному (проекту)"). На практике обычно каждый служащий работает над несколькими проектами (отношение "многие-ко-многим"). Чтобы реализовать такое отношение, необходимо модернизировать структуру физической базы данных. Определим отношение "многие-ко-многим" через создание новой таблицы EMP_PRJ
CREATE TABLE EMP_PRJ ( EMPNO integer NOT NULL, PROJNO char(8) NOT NULL, WORKS number, PRIMARY KEY (EMPNO, PROJNO), FOREIGN KEY (EMPNO) REFERENCES EMPLOYEE, FOREIGN KEY (PROJNO) REFERENCES PROJECT, );
которая будет служить для распределения служащих по проектам. В этой таблице каждому служащему отвечает столько строк, сколько проектов он выполняет. Схема базы данных примет теперь вид как на рис. 9.1. Колонка PROJNO таблицы EMPLOYEE при этом потеряла свой семантический смысл. Ee следует удалить из таблицы EMPLOYEE за ненадобностью.
(рис 9.1) Логическая структура учебной базы данных после разрешения отношения "многие-ко-многим"
Как работать с
CREATE TABLE DEPARTAMENT ( DEPNO integer NOT NULL, DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), PRIMARY KEY (DEPNO) определение первичного ключа ); CREATE TABLE EMPLOYEE ( EMPNO integer NOT NULL, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), JOB char(25), AGE date, HIREDATE date NOT NULL WITH DEFAULT, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), PRIMARY KEY (EMPNO) ); CREATE TABLE PROJECT ( PROJNO char(8) NOT NULL, PNAME char(25), BUDGET dec(9,2), PRIMARY KEY (PROJNO) ); CREATE TABLE EMP_PRJ ( EMPNO integer NOT NULL, PROJNO char(8) NOT NULL, WORKS number, PRIMARY KEY (EMPNO, PROJNO), FOREIGN KEY (EMPNO) REFERENCES EMPLOYEE, FOREIGN KEY (PROJNO) REFERENCES PROJECT );
Таким образом, в результате описанных выше действий был получен скрипт для создания
Дальнейшими задачами проектировщика базы данных будут задачи усовершенствования и доработки разработанного скрипта в следующих направлениях:
Первые три направления деятельности носят опциональный характер и определяются особенностями конкретного ИТ-проекта и вкусами руководителя данного проекта, а также требованиями к базе данных и бизнес-правилами предметной области, если они представлены в исходной документации. Часто, особенно при использовании объектно-ориентированной парадигмы в разработке приложений базы данных, эти три направления деятельности проектировщика базы данных могут быть переданы разработчикам приложений базы данных. Поэтому мы подчеркиваем здесь их необязательный характер. Как может решать такие задачи проектировщик базы данных, будет рассмотрено в других разделах этой лекции. Четвертое направление деятельности очень желательно. Его следует выполнять, если априорно имеются данные о возможном поведении данных в системе во времени. Обычно борьба за производительность относится к задачам обратного влияния, когда становятся известными параметры эксплуатации системы. Это направление деятельности будет рассматриваться в двух последующих лекциях.
Последнее направление деятельности носит обязательный характер для обеспечения функционирования базы данных, эта задача в большей степени является задачей
Ниже приведен типичный синтаксис некоторых команд SQL.
Синтаксис оператора CREATE TABLE:
CREATE TABLE имя_таблицы (имя_колонки тип_данных [NOT NULL | NOT NULL WITH DEFAULT] [, имя колонки ѕ] [PRIMARY KEY (имя_колонки [,имя_колонки ѕ]] [FOREIGN KEY [имя_ключа] (имя_колонки [, имя_колонки ѕ ]) REFERENCES имя_таблицы_родителя [ON DELETE [RESTRICT | CASCADE | SET NULL]]] ) [IN [имя_базы_данных] имя_области_табличного_пространства | IN DATABASE имя_базы_данных] [PCTFREE целочисленная_константа]
Примечание. Здесь и ниже опции операторов SQL, которые не объясняются в настоящем разделе книги, поясняются далее, там, где логика изложения требует их детального обсуждения. Подчеркивание ключевого слова обозначает значение, принятое по умолчанию.
Синтаксис оператора CREATE INDEX:
CREATE [UNIQUE] [CLUSTERED HASHED] INDEX имя_индекса ON имя_таблицы (имя_колонки [ASC | DESC] [, имя_колонки ѕ]) [PCTFREE целочисленная_константа] [SIZE целочисленное_значение [ROWS | BUCKETS]]
В предыдущих разделах мы уже сталкивались с несколькими NOT NULL, и ограничениях в таблицах - PRIMARY KEY, FOREING KEY. В данном разделе мы изучим практически все виды ограничений, которые поддерживаются в реляционных базах данных. Ограничения являются важным инструментом проектировщика базы данных, с помощью которого он поддерживает целостность (strong) базы данных. Их можно использовать для того, чтобы быть уверенным в том, что колонка первичного ключа таблицы является уникальной и всегда содержит значения. Ограничения используются также для
Замечание. Одна из главных концепций реляционной базы данных состоит в том, что всегда целесообразнее заставлять саму базу данных поддерживать свою непротиворечивость, чем заставлять решать эту задачу приложение базы данных. Вопрос о том, что лучше: передавать поддержку ограничений приложениям базы данных или оставлять самой базе данных, - остается все еще открытым.
Ограничения представляют собой способ применения бизнес-правил предметной области на уровне базы данных и гарантируют совместимость вводимых данных с теми, которые уже находятся в таблицах. В реляционной базе данных под ограничением понимается правило (условие), которому должен удовлетворять некоторый элемент в базе данных. Например, условия, которым должны дополнительно удовлетворять значения колонки таблицы в рамках определенного для нее типа данных (т.е. тип данных плюс правило), полностью воплощают концепцию домена в
Как мы видели выше, ограничения могут применяться на уровне колонки (ограничения колонки) или SQL NOT NULL, UNIQUE, CHECK.
| Ограничение | Описание | |
| 1 | CHECK |
гарантирует, что значения находятся в границах специфицированного интервала, задаваемого предикатом |
|---|---|---|
| 2 | DEFAULT |
помещает значение по умолчанию в колонку. Гарантирует, что колонка всегда имеет значение |
| 3 | FOREIN KEY |
гарантирует, что значения существует как значение в колонке первичного ключа другой таблицы. Обеспечивает процедуры удаления дочерних строк при удалении связанных с ней родительских |
| 4 | NOT NULL |
гарантирует, что колонка всегда содержит значение |
| 5 | PRIMARY KEY |
гарантирует, что колонка всегда содержит значение и оно уникально в таблице |
| 6 | UNIQUE |
гарантирует, что значение будет уникальным в таблице |
Ограничение CHECK позволяет выполнять проверку содержимого колонки относительно некоторых условий и списка значений. Она налагается с помощью предложения CHECK. Для добавления этого ограничения нужно после объявления столбца в спецификации колонки определить синтаксическую конструкцию CHECK (предикат). Согласно требованиям стандарта с помощью ключевого слова VALUE в предикате вы ссылаетесь на значение колонки. Но практически во всех диалектах для этой цели используется имя колонки.
Пример. В учебной базе данных в таблице
EMPLOYEEдля сотрудников может указываться признак пола: 0 - мужской, 1 - женский. Бизнес-правило предметной области для значений этого поля может быть сформулировано так:
Лицо, принимаемое на работу, может иметь один из двух допустимых признаков пола.
Тогда
SEX int NOT NULL CHECK (SEX=0 OR SEX=1),
Опция DEFAULT заставляет СУБД размещать значение по умолчанию в колонке, когда кортеж вставляется в таблицу и никакого значения колонки не представлено. Чтобы указать значение по умолчанию, нужно в
Пример. Для нашей учебной базы данных мы могли бы определить значение по умолчанию для числовых колонок в таблице EMPLOYEE:
SAL dec(9,2) DEFAULT(0), COMM dec(9,2) DEFAULT(0), FINE dec(9,2) DEFAULT(0),
NOT NULL ограничение гарантирует, что колонка всегда содержит значения. СУБД не будет разрешать вставлять или обновлять строку таблицы, если в ней существует колонка с ограничением NOT NULL, а данных для этой колонки в добавляемой строке не представлено. Как мы уже видели выше, для колонок первичного ключа это ограничение нужно устанавливать всегда.
Пример. Для нашей учебной базы данных действует правило, что сотрудник всегда должен иметь имя и фамилию. Чтобы удовлетворить этому правилу, нужно определить следующую спецификацию колонок
ENAMEиLNAMEв таблицеEMPLOYEE:
ENAME char(25) NOT NULL, LNAME char(10) NOT NULL,
Иногда ограничение NOT NULL используется вместе с опцией DEFAULT, как это было определено в спецификации колонки HIREDATE (дата приема на работу) в таблице EMPLOYEE:
HIREDATE date NOT NULL WITH DEFAULT,
Мы уже рассматривали вопрос о задании
Ограничение UNIQUE гарантирует уникальность значения данных в колонке. Оно используется, если нужно следить за тем, чтобы значения колонки, не являющейся первичным ключом, были уникальны в таблице. При этом проверяется уникальность всех значений, отличных от NULL.
Пример. В учебной базе данных в таблице
EMPLOYEEиспользуется номер социальной страховки SSECNO, для которого бизнес-правило состоит в том, что для каждой персоны, если она имеет такой номер, он должен быть уникальным. Установить уникальность этих номеров можно следующей спецификацией колонки:
SSECNO char(10) UNIQUE,
Ограничение UNIQUE можно определить также в конце команды CREATE TABLE в следующей синтаксической форме: UNIQUE (SSECNO).
Ограничения задаются в спецификациях колонки или спецификациях ключей при создании таблицы в командах SQL CREATE TABLE или налагаются после создания таблицы в командах SQL . Как добавить ограничения в таблицу с помощью команды CREATE TABLE, мы уже знаем. Чтобы добавить ограничения с помощью команды , можно поступать следующим образом.
Пример. Для нашей учебной базы данных мы могли бы не определять первичный ключ в таблице
EMPLOYEEв командеCREATE TABLEи после нее выполнить команду
ALTER TABLE EMPLOYEE PRIMARY KEY (EMPNO);
Аналогично, мы могли бы установить ограничение внешнего ключа в таблице EMP_PRJ следующим образом:
CREATE TABLE EMP_PRJ ( EMPNO integer NOT NULL, PROJNO char(8) NOT NULL, WORKS number, PRIMARY KEY (EMPNO, PROJNO), ); ALTER TABLE EMP_PRJ FOREING KEY (EMPNO) REFERENCES EMPLOYEE ON DELETE RESTRICT, FOREING KEY (PROJNO) REFERENCES PROJECT ON DELETE RESTRICT;
Чтобы удалять ограничения первичного и внешнего ключей, можно использовать команду в синтаксической форме
ALTER TABLE EMPLOYEE DROP PRIMARY KEY (EMPNO);
В СУБД Oracle 9i для создания :
ALTER TABLE имя_таблицы ADD CONSTRAINTS ограничение TYPE(колонка);
а для удаления
ALTER TABLE имя_таблицы DROP CONSTRAINTS ограничение.
Кроме этого, в СУБД Oracle 8i можно блокировать и деблокировать действие ограничений с помощью опций DISABLE и ENABLE команды , как показано в примере ниже:
ALTER TABLE EMPLOYEE DISABLE PRIMARY KEY; ALTER TABLE EMPLOYEE ENABLE PRIMARY KEY;
После использования опции DISABLE ограничение становится неактивным, но его определение остается в словаре базы данных. Вы можете вернуть ENABLE. Использование опции DROP полностью удаляет ограничение из базы данных (и словаря базы данных также).
В реляционной теории концепция
Допустимость ссылки еще не означает ее корректность. Так, в учебной базе данных вы можете приписать служащему в таблице EMPLOYEE несуществующий номер отдела. Однако значение номера отдела в этой таблице должно быть согласовано с соответствующим значением в таблице DEPARTAMENT. Поддержка DEPARTAMENT. При этом вставка служащего с неправильным номером отдела будет заблокирована. Однако правильность списка сотрудников отдела не контролируется. Допустимая ссылка еще не означает ее правильность.
Иными словами,
Такие ограничения (в виде бизнес-правил) определяются при
В настоящее время большинство промышленных реляционных СУБД имеют встроенный механизм
Механизм
Понятие первичного ключа как уникального идентификатора кортежа отношения уже обсуждалось выше. Здесь нас интересует другой аспект данного понятия. А именно - то, что первичный ключ может гарантировать целостность данных. Если первичный ключ корректно используется, все
Поддержка
Замечание. В СУБД Oracle 9i первичный индекс создается автоматически.
В конкретных реализациях СУБД существуют дополнительные ограничения на определение первичного ключа. Так, в SQLBase первичный ключ не может включать более 16 колонок, общая длина первичного ключа не может превышать 255 байт, нельзя использовать колонки типа LONG/LONG VARCHAR, в самоссылающихся строках значение первичного ключа невозможно модифицировать.
Внешний ключ представляет собой ссылку на первичный ключ в данной или другой таблице, т.е. один или несколько атрибутов отношения, которые содержат первичный ключ другого отношения. Примером внешнего ключа является номер отдела DEPNO в таблице EMPLOYEE нашей учебной базы данных.
Из определения следует, что внешний ключ может быть создан только после создания соответствующего первичного ключа (и первичного индекса). Внешнему ключу обычно назначается специальное имя. Внешние ключи имеют следующие свойства:
Поддержка
В SQLBase существуют ограничения на определение внешнего ключа:
В других СУБД ограничения на определение внешнего ключа носят аналогичный характер.
Первичный и соответствующий ему внешний ключ позволяют реализовать отношение "родитель-потомок" (parent/child
Таблица реляционной базы данных, содержащая первичный ключ, называется таблицей-родителем (parent table) или DEPARTAMENT учебной базы данных является таблицей-родителем для таблицы EMPLOYEE.
Таблица базы данных может не иметь ни родителей, ни потомков. Такие таблицы называются независимыми таблицами (
Отношение "родитель-потомок" между таблицами реализуется через атрибуты-ключи соответствующих строк. Строка, принадлежащая
Совсем необязательно, чтобы каждая строка таблицы-родителя была родительской строкой. Аналогично, если строка в таблице-потомке имеет нуль-значение внешнего ключа, то она не будет строкой-потомком.
Отношение "родитель-потомок" между двумя таблицами отражает взаимосвязь по включению на доменах соответствующих атрибутов. Однако, таблица может реализовать отношение иерархического подчинения в самой себе. Примером такой таблицы может стать
Таблицы называются связанными по удалению (delete-connected tables), если удаление строки в одной таблице влияет на состояние строк в другой таблице. Так, если в таблице DEPARTAMENT удалить отдел (в связи с его ликвидацией), то в таблице EMPLOYEE необходимо либо удалить некоторых служащих этого отдела (уволились), либо изменить у них номер отдела (переведены в другой). Любая таблица, которая участвует в операции удаления при ограничениях
Также ясно, что самоссылающаяся таблица является связанной по удалению сама с собой,
Для создания таблиц с поддержкой ограничений CREATE TABLE и команда . Таким образом, вы имеете два основных способа для
PRIMARY KEY и FOREIGN KEY команды CREATE TABLE ;ADD/DROP PRIMARY KEY и ADD/DROP FOREIGN KEY команды ALTER TABLE .В предыдущих разделах уже было показано использование предложения PRIMARY KEY команды CREATE TABLE. Пример использования предложения команды CREATE TABLE продемонстрируем на примере создания таблицы для иерархии "руководитель-подчиненный":
CREATE TABLE MANAGEMENT ( MANAGNO INT NOT NULL, EMPNO INT, JOB INT, PRIMARY KEY (MANAGNO), FOREIGN KEY fnkey (EMPNO) REFERENCES EMPLOYEE ON DELETE CASCADE); CREATE UNIQUE INDEX ndxmng ON MANAGEMENT(MANAGNO);
fnkey - имя внешнего ключа, предложение REFERENCES, связанное с предложением , определяет имя таблицы-родителя, предложение ON DELETE определяет правило удаления записей в связанных таблицах. Каждое правило удаления соответствует определенной взаимосвязи между объектами реляционной базы данных (т. е. предметной области).
Правила удаления используются только в определении внешнего ключа. Обычно СУБД в соответствии со стандартом SQL поддерживает три правила:
CASCADE - сначала удаляется заданная строка в RESTRICT - строка может быть удалена, если никакие другие строки не зависят от нее, в противном случае удаления не происходит;SET NULL - для любого удаляемого первичного ключа соответствующее ему значение внешнего ключа дочерней строки принимает нуль-значение.Для самоссылающихся таблиц используется только правило CASCADE. Правило RESTRICT препятствует удалению строки в таблице-родителе, если ей соответствуют какая-либо строка в таблице-потомке. Правило CASCADE определяет, что, когда строка в таблице-родителе удаляется, то все связанные с ней строки в таблице-потомке автоматически должны быть удалены. Правило определяет, что, когда строка в
Применение команды продемонстрируем на примере создания отношения "родитель-потомок" для таблиц DEPARTAMENT и EMPLOYEE учебной базы данных. Первичные ключи и индексы для этих таблиц уже созданы. Создадим внешние ключи (в таблицу DEPARTAMENT должна быть добавлена колонка EMPNO ).
ALTER TABLE DEPARTAMENT FOREIGN KEY EMP_DEP (EMPNO) REFERENCES EMPLOYEE ON DELETE RESTRICT;
Для того, чтобы удалить первичный или внешний ключ таблицы, необходимо использовать предложение DROP команды .
Естественно, что ограничения
Для команды INSERT предусмотрены следующие правила:
NOT NULL значение атрибута внешнего ключа должно соответствовать значению атрибута первичного ключа в таблице-родителе;Для команды UPDATE предусмотрены следующие правила:
Попытка обновить первичный ключ UPDATE.
Правила для команды DELETE сообщают СУБД, что ей делать, когда пользователь пытается удалить строку в таблице-родителе. Отметим также, что в командах удаления нельзя использовать
Применение команды DROP в условиях ограничений
Использование ограничений EMPLOYEE содержит колонку DEPNO (внешний ключ, содержащий ссылку на таблицу DEPARTAMENT ). Если добавить в таблицу EMPLOYEE колонку MNGR, которая определяет руководителя каждого служащего, а в таблицу DEPARTAMENT - колонку с номером руководителя MRGNO, то мы получим пример ссылочного цикла (при определении
Такой вид циклической связи порождает проблемы для операций манипулирования данными. Допустим, что на работу принят служащий, который должен руководить вновь созданным отделом 100. Последовательное выполнение операторов INSERT будет неуспешным (строка в дочерней таблице EMPLOYEE ссылается на отдел, которого еще нет, и такого менеджера еще не существует).
INSERT INTO EMPLOYEE (EMPNO,ENAME,LNAME,DEPNO,
JOB,AGE,HIREDATE,SAL,COMM,FINE,MNGR)
VALUES(4000,"Анисимов","Виктор",100,"Менеджер",,2500000,,,NULL);
INSERT INTO DEPARTAMENT
(DEPNO, DNAME, LOC, MANAGER, MRGNO,PHONE)
VALUES (100,'Маркетинг','Москва', 'Анисимов', 4000,1352519);
Операция добавления в базу данных записей, связанных с организацией нового отдела и прихода его руководителя, при
INSERT INTO EMPLOYEE (EMPNO,ENAME,LNAME,DEPNO,
JOB,AGE,HIREDATE,SAL,COMM,FINE,MNGR)
VALUES(4000, "Анисимов","Виктор",NULL, "Менеджер",,2500000,,,NULL);
INSERT INTO DEPARTAMENT
(DEPNO, DNAME, LOC, MANAGER, MRGNO,PHONE)
VALUES (100,'Маркетинг','Москва', 'Анисимов', 4000,1352519);
UPDATE EMPLOYEE
SET DEPNO=100
WHERE EMPNO=4000;
Аналогичным образом могут, при наличии ссылочных циклов, возникать проблемы с операцией удаления кортежей в родительской и
Более подробное описание работы с ограничениями
В этом разделе мы изучили ограничения, которые поддерживаются в реляционной базе данных средствами СУБД. Такие ограничения представляют встроенные в СУБД механизмы обеспечения целостности данных и
Ниже приведен типичный синтаксис команды .
Типичный синтаксис команды (без учета
ALTER TABLE имя_таблицы DROP [имя_колонки [,имя_колонки ѕ]] ADD имя_колонки тип_данных [(размер)] [NOT NULL | NOT NULL WITH DEFAULT] RENAME имя_колонки новое_имя | TABLE новое_имя MODIFY имя_колонки тип_данных [(размер)] [NULL | NOT NULL | NOT NULL WITH DEFAULT]
СУБД предоставляет вам возможность создавать представления или так называемые
Примечание. Далее в тексте термины "представление" и "
виртуальная таблица " будут употребляться на равных правах.
Для создания виртуальных таблиц в SQL предназначена команда . Пусть вам требуется регулярно просматривать списки служащих по отделам. Тогда вы можете использовать
CREATE VIEW EMPLIST AS SELECT DEPNO, EMPNO, ENAME, JOB FROM EMPLOYEE GROOP BY DEPNO, EMPNO, ENAME, JOB;
Как видите, SELECT. Как известно, результат выполнения команды SELECT является таблицей. GROUP BY, иногда называется групповым представлением (grouped view)
Как только промежуточная таблица получает имя, к ней можно делать запрос. Например, выполнить команду
SELECT * FROM EMPLIST WHERE DEPNO=10;
которая дает список сотрудников 10-го подразделения.
Однако во многих реализациях SQL представления имеют сильные ограничения на выполнение операций обновления данных над ними. Некоторые СУБД не разрешают в определении представления использовать предложение ORDER BY. В некоторых диалектах SQL недопустимо выполнение обновлений на виртуальных таблицах, определенных на нескольких GROUP BY, HAVING, опцию и функции агрегирования. Такие представления используются только для чтения. Например, в СУБД SQLBase представление используется только для чтения (read-only view), если в определяющей команде SELECT:
FROM задействует имена более одной таблицы или представления;DISTINCT ;GROUP BY ;HAVING ;Иногда запрещается использовать и
В противном случае представление считается обновляемым представлением (updatable view). Для обновляемых представлений предусмотрена опция WITH CHECK OPTION. Когда она указана, любая вставка и обновление через данное представление будет выполняться только, если представление отвечает своему определению (данные в таблице могут быть изменены непосредственно). В противном случае такой проверки не делается. Если представление предназначено только для чтения или применяет
Команда с такими же ограничениями также выполнима на виртуальных таблицах.
Если вам необходимо работать с несколькими таблицами как с одной, вы можете создать
CREATE VIEW PERSPROJ AS SELECT ENAME, JOB, PNAME FROM EMPLOYEE, PROJECT WHERE EMPLOYEE.PROJNO=PROJECT.PROJNO;
Выполняя команду
SELECT * FROM PERSPROJ;
вы получите необходимую вам информацию. При этом вам не нужно помнить, что данные хранятся в двух таблицах. Даже если будет изменена структура базы данных, не затрагивающая колонки из виртуальной таблицы, вы этого не заметите.
Можно выполнять и более сложные запросы на виртуальных таблицах. Допустим, что вам нужен список руководителей по проектам, тогда вы можете выполнить
SELECT ENAME, PNAME FROM PERSPROJ WHERE JOB='руководитель';
С виртуальными таблицами используется предложение WITH CHECK OPTION. При этом каждая вставка или обновление будет проверяться на соответствие определению виртуальной таблицы и будет отвергаться, если такого соответствия не будет. В противном случае такой проверки не делается.
Пусть вам нужно иметь информацию о текущих проектах. Тогда можно определить START_DATE в таблице PROJECT и установив его значения) как
CREATE VIEW CURPROJ AS SELECT * FROM PROJECT WHERE START_DATE < SYSDATE WITH CHECK OPTION;
Колонка START_DATE при обновлении будет проверяться на соответствие текущей дате. Это предложение справедливо только для обновления данных в колонках WITH CHECK OPTION не должно указываться.
Как вы могли видеть,
Рассмотрим пример из предыдущего раздела. Примененная схема базы данных учебного примера не позволяет использовать одного служащего в нескольких проектах (реализовано отношение "много (служащих) к одному (проекту)"). На практике обычно каждый служащий работает над несколькими проектами (отношение "многие-ко-многим"). Чтобы реализовать такое отношение, необходимо модернизировать структуру базы данных. При этом все ранее разработанные приложения и PREM:
CREATE TABLE PREM ( EMPNO integer, PROJNO char(8), WORKS number);
которая будет служить для распределения служащих по проектам. В этой таблице каждому служащему отвечает столько строк, сколько проектов он выполняет. Колонка PROJNO таблицы EMPLOYEE при этом потеряла свой семантический смысл. Удалим эти данные:
UPDATE EMPLOYEE SET PROJNO=NULL;
При этом мы уже не можем пользоваться виртуальной таблицей PERSPROJ, которая использует эту колонку для соединения таблиц EMPLOYEE и PROJECT. Чтобы для пользователя ничего не изменилось, следует переопределить PERSPROJ. Для этого удалим ее с помощью команды SQL DROP. Команда DROP является в SQL универсальной командой для удаления объектов реляционной базы данных: вы только должны определить, что вы хотите удалить: TABLE, VIEW или иной объект.
Удалим определение неподходящей виртуальной таблицы:
DROP VIEW PERSPROJ;
Создадим новую
CREATE VIEW PERSPROJ AS SELECT ENAME, JOB, PNAME FROM EMPLOYEE, PROJECT, PREM WHERE EMPLOYEE.EMPNO=PREM.EMPNO AND PREM.PROJNO=PROJECT.PROJNO;
Колонку PROJNO в таблице EMPLOYEE следует удалить за ненадобностью:
ALTER TABLE EMPLOYEE DROP PROJNO;
Вы видите, как легко изменить структуру базы данных, не внося слишком больших изменений в ваши приложения и используемые запросы (на виртуальных таблицах). Это объясняется тем, что SQL является непроцедурным языком, т.е. ваши программы и запросы не привязываются к структуре базы данных. За счет модификации виртуальных таблиц вы можете скрыть фактические изменения структуры базы данных от пользователя. Рассмотренный выше пример иллюстрирует основные моменты реализации концепции независимости данных в реляционных базах данных.
Представления (
Концепция представления особенно важна, когда требуется извлекать информацию из нескольких отношений. Во-первых, она является средством формирования пользователем своей виртуальной (внешней) схемы базы данных. Во-вторых, это средство формирования производных или выводимых атрибутов отношений базы данных, то есть таких атрибутов, которые непосредственно не хранятся в базе данных. Представление можно трактовать как
Обратимся к примеру с футболом. Пусть имеется некоторая база данных, которая содержит всю информацию о чемпионате мира по футболу. Допустим, что вас интересует информация о стадионах и об играх, закончившихся с определенной разностью забитых и пропущенных мячей. Тогда вы можете первоначально определить представление как
CREATE VIEW СТАДРАЗН (стад, разн_мячей ) AS SELECT стадион, голыА - голыВ FROM ИГРЫ, РАЗМ_СТАДИОНОВ WHERE ИГРЫ.год = РАЗМ_СТАДИОНОВ.год AND ИГРЫ.группа = 2 АND РАЗМ_СТАДИОНОВ.группа=2 АND ИГРЫ.игра=РАЗМ_СТАДИОНОВ.игра
В этом примере также демонстрируется, как определять производные колонки в представлении.
Теперь вы можете выполнить запрос к виртуальной таблице, такой, чтобы получить ответ на вопрос: выдать все стадионы, на которых игры закончились с разностью мячей больше 4. Команда языка SQL в этом случае тривиальна:
SELECT стад FROM СТАДРАЗН WHERE разн_мячей > 4;
Таким образом, представление в алгебре отношений является операцией наименования промежуточных результатов.
Синоним есть другое имя для таблицы или представления. Синонимы используются для того, чтобы сделать базу данных более дружественной для пользователя. Это означает, что объектам базы данных, которые попадают в сферу внимания пользователей, назначаются альтернативные, длинные имена в терминах предметной области базы данных. Такие имена более понятны неподготовленным
Задача назначения синонимов объектам базы данных является задачей
Синоним по определению может быть общим для всех PUBLIC ) или принадлежать пользователю (USER), который его создал. Опция PUBLIC позволяет обращаться к таблице с помощью синонима без уточнения имени таблицы именем владельца. Чтобы создать или удалить синоним PUBLIC, необходимо либо быть владельцем таблицы, либо иметь привилегии пользователей SYS или SYSTEM (Oracle). (Для СУБД SQLBase
Пример. Для нашей учебной базы данных вы можете создать синоним EMP для таблицы
EPMPLOYEEс помощью следующей команды:
CREATE PUBLIC SYNONYN EMP FOR EPMPLOYEE;
Или для пользователя SYS:
CREATE SYNONYN SYS.EMPL FOR EPMPLOYEE;
Чтобы удалить синоним EMP таблицы EPMPLOYEE, необходимо использовать команду
DROP PUBLIC SYNONYN EMP;
При обсуждении представлений мы уже касались понятия внешней схемы. В этом подразделе мы остановимся на этом понятии более подробно. Создание внешней схемы является желательным, но совсем не обязательным действием проектировщика данных.
В архитектуре трех схем ANSI/SPARC внешняя схема используется для изоляции требований к данным пользователей и приложений от физического размещения данных. Такая изоляция по определению делает пользователей независимыми от аспектов
В настоящее время стандарт SQL, так же как и большинство промышленных СУБД, не говоря уже об экспериментальных СУБД, обеспечивают поддержку внешней схемы ограниченно. Основным способом изоляции требований пользователей к данным от особенностей их физического хранения является механизм реляционных представлений, который мы обсуждали выше.
Приведем примеры, когда изменения на уровне физической организации базы данных могут быть скрыты от пользователей с помощью представлений.
Создание внешней схемы является в большей степени задачей
Однако, если руководителем ИТ-проекта принято решение о разработке внешней схемы, проектировщик должен создать первоначальный вариант внешней схемы.
Для того чтобы создать внешнюю схему для новой базы данных, проектировщику базы данных необходимо начать с создания так называемых зеркальных представлений. Такое представление разрабатывается для каждой базовой таблицы
Дополнительные представления могут быть созданы для приложений, которые выполняют так называемые типовые запросы к базам данных. Под типовым запросом здесь понимается запрос, который выполняется с высокой частотой использования либо одним пользователем, либо группой пользователей. Такое представление проектировщик базы данных может разработать, если требования к обработке данных задокументированы в спецификациях к базе данных.
Представления для эпизодических
Создавать внешнюю схему наиболее удобно параллельно с внутренней, по мере того как создаются
Пример. Для нашей учебной базы данных первоначальная внешняя схема может выглядеть следующим образом:
CREATE VIEW DEPARTAMENT_V AS SELECT DEPNO, DNAME, LOC, MANAGER, PHONE FROM DEPARTAMENT; CREATE VIEW EMPLOYEE_V AS SELECT EMPNO, ENAME, LNAME, DEPNO, SSECNO, JOB, AGE, HIREDATE, SAL, COMM, FINE FROM EMPLOYEE; CREATE VIEW PROJECT_V AS SELECT PROJNO, PNAME, BUDGET FROM PROJECT; CREATE VIEW PERSPROJ AS SELECT ENAME, JOB, PNAME FROM EMPLOYEE, PROJECT, EMPL_PROJ WHERE EMPLOYEE.EMPNO= EMPL_PROJ.EMPNO AND EMPL_PROJ.PROJNO=PROJECT.PROJNO;
Проектировщик базы данных в данном случае решил создать зеркальные представления для _V в именах представлений, для того чтобы указать, что эти представления зеркально отображают поля базовой таблицы с именем без суффикса.
Кроме этого, он добавил представление, позволяющее получать информацию о служащих и выполняемых ими проектах, которая включает связывающую таблицу для этого отношения со степенью связи "многие-ко-многим".
В этом разделе мы рассмотрели механизм представлений реляционной базы данных. Представления как объекты базы данных занимают немного физического пространства в словаре базы данных, но обеспечивают функциональность базы данных на уровне таблиц. Помимо прочего они позволяют скрывать от пользователей информацию о физической структуре таблиц базы данных, что повышает безопасность эксплуатации базы данных в целом. Представления являются в реляционных базах данных основным механизмом для построения внешней схемы базы данных.
Ниже приведены рекомендации проектировщикам баз данных по созданию представлений в типичной реляционной базе данных.
В настоящем разделе будет рассмотрена первая профессиональная задача проектировщика базы данных по созданию
В рамках концепции
Таким образом, SQL. Выполнение этой последовательности команд создает конкретную базу данных и ее объекты.
Одной из основных задач проектировщика данных при создании
Элементарной подзадачей является создание таблицы базы данных. Таблицы в реляционных СУБД1 состоят из одной или более колонок или полей. Колонки представляют собой поименованные ячейки в записи, которые содержат значения. Колонки определяются посредством спецификации, которая определяет формат колонки и ее характеристики, задаваемые с помощью ограничений. Определение таблицы задается командой CREATE TABLE.
С точки зрения
CREATE TABLE для каждой СУБД приводится в соответствующем документе с названием типа "Справочное руководство по SQL для СУБДѕ".
Как указывалось выше, первый шаг в построении CREATE TABLE, которые будут использоваться далее для добавления колонок и других деталей.
Далее проектировщик базы данных формирует список всех пользователей каждой таблицы. При этом выделяются так называемые владельцы таблицы, т.е. пользователи, которые имеют все права доступа к таблице. Этот список используется на завершающем этапе проектирования
Когда проектировщик заканчивает обработку всех отношений
Пример. Для нашего учебного примера результат решения задачи настоящего пункта может иметь следующий вид:
CREATE TABLE DEPARTAMENT имя таблицы ( ); CREATE TABLE EMPLOYEE имя таблицы ( ); CREATE TABLE PROJECT имя таблицы ( );
Следующим шагом проектировщика базы данных является определение колонок для CREATE TABLE.
Сначала рассмотрим задачу добавления колонок. Колонка должна иметь имя. Имена атрибутов соответствующих отношений логической модели преобразуются в имена колонок в соответствии с правилами именования объектов, принятых в конкретной СУБД. Обычно, как указывалось выше, это ограничение на длину имени и использование в имени специальных символов. Например, в некоторых СУБД допускается использовать знак доллара в имени, однако этот знак обычно не распознается в командах выборки данных - SELECT.
Имеется еще одна проблема в именовании колонок: имена колонок должны интерпретироваться пользователем однозначно. Например, если проектировщик базы данных назначит для фамилии сотрудника короткое имя LN, то, наверное, потребуется комментарий, в котором необходимо указать, что это фамилия, а не линия (например, линия производства). Если невозможно по каким-то причинам применять длинные имена полей, то следует использовать словарь данных для интерпретации введенных аббревиатур.
При назначении имен колонок проектировщик базы данных продолжает формировать стандартный список имен колонок и их сокращений в словаре данных. Он также должен выполнить проверку списка имен в словаре данных, чтобы избежать конфликтов имен в базе данных в целом.
Пример. Продолжим работу с учебным примером. После именования колонок получим следующее:
CREATE TABLE DEPARTAMENT ( DEPNO, имя колонки DNAME, LOC, MANAGER, PHONE, ); CREATE TABLE EMPLOYEE ( EMPNO, ENAME, LNAME, DEPNO, SSECNO, PROJNO, JOB, AGE, HIREDATE, SAL, COMM, FINE, ); CREATE TABLE PROJECT ( PROJNO, PNAME, BUDGET, );
После идентификации колонок необходимо задать их тип в соответствии с допустимыми для данной СУБД типами данных. Эта задача упрощается, если в отношениях логической модели определены домены атрибутов. Некоторые из доменов могут быть определены уже в терминах СУБД. Для таких атрибутов практически ничего делать не нужно. Определение домена в терминах типа данных СУБД нужно просто перенести в DEC (9,2), а из контекста предметной области следует, что в этой колонке будет накапливаться итоговая сумма расходов за год, то может быть целесообразным определить тип как DEC (15,2), чтобы избежать возможного переполнения при работе приложений базы данных.
Если домен определен не в терминах СУБД, проектировщик базы данных должен преобразовать его в подходящий тип данных. При выполнении таких преобразования следует учитывать ряд факторов.
varchar (3), которая содержит код, чье значение изменяется в интервале от '10A' ' до '99Z', то целесообразно с точки зрения хранения изменить тип этой переменной на char (3). Это объясняется тем, что тип varchar при физическом хранении занимает на байт-два больше, чем тип char при одной и той же объявленной длине.DEC. Он обрабатывается процессором быстрее, чем тип FLOAT. Исключение составляют данные для научных расчетов, где представление чисел в экспоненциальной форме бывает необходимо.INT и SMALLINT исключительно для счетчиков.LONG VARCHAR без лишней надобности. Обычно колонки такого типа хранятся на отдельном экстенте жесткого диска, причем не в той области диска, где хранятся остальные данные таблицы.CHAR для представления числовых данных. Во-первых, может потребоваться дополнительная проверка, а во-вторых, могут возникнуть проблемы при сортировке таких колонок, поскольку число, заданное строкой '11', будет находиться выше, чем число, заданное строкой '9', при упорядочивании по возрастанию.DATE и TIME только для хранения хронологических данных.DATETIME исключительно для целей управления данными.Пример. Продолжим изучение нашего примера. После определения типов колонок наши команды для создания таблиц будут выглядеть следующим образом:
CREATE TABLE DEPARTAMENT ( DEPNO integer, имя колонки, тип, длина DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), ); CREATE TABLE EMPLOYEE ( EMPNO integer, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), PROJNO char(8), JOB char(25), AGE date, HIREDATE date, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), ); CREATE TABLE PROJECT ( PROJNO char(8), PNAME char(25), BUDGET dec(9,2), );
После определения всех колонок и их типов следует перейти к идентификации первичных ключей таблицы. Согласно требованиям реляционной теории каждая строка таблицы (кортеж) должна иметь уникальный первичный ключ. Обычно хорошим кандидатом на первичный ключ таблицы является CREATE TABLE. Такое определение первичного ключа таблицы для многих таблиц не является окончательным. Переопределение первичного ключа может происходить на следующих этапах физического
Задание колонки как первичного ключа в контексте многих СУБД, в том числе и Oracle, считается ограничением на значение колонки (см. следующий подраздел).
PRIMARY KEY команды CREATE TABLE для спецификации первичного ключа таблицы. Атрибуты первичного ключа перечисляются через запятую и заключаются в круглые скобки. Если спецификация PRIMARY KEY не определяется, то считается, что таблица не имеет первичного ключа. При этом допускается дублирование строк в таблице.
Пример. Для нашего примера колонками первичного ключа могут быть назначены: колонка DEPNO в отношении DEPARTAMENT, колонка EMPNO в отношении EMPLOYEE, колонка PROJNO в отношении PROJECT.
CREATE TABLE DEPARTAMENT ( DEPNO integer, DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), PRIMARY KEY (DEPNO) определение первичного ключа ); CREATE TABLE EMPLOYEE ( EMPNO integer, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), PROJNO char(8), J OB char(25), AGE date, HIREDATE date, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), PRIMARY KEY (EMPNO) ); CREATE TABLE PROJECT ( PROJNO char(8), PNAME char(25), BUDGET dec(9,2), PRIMARY KEY (PROJNO) );
В СУБД Oracle можно задавать CREATE TABLE будет выглядеть так, как показано ниже для таблицы DEPARTAMENT:
CREATE TABLE DEPARTAMENT ( DEPNO integer primary key, определение первичного ключа DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), );
Когда вы определяете PRIMARY KEY при создании таблицы, многие реляционные СУБД требуют обязательного создания уникального
CREATE UNIQUE INDEX NDXDEPT ON DEPARTAMENT (DEPNO);
Предложение CREATE INDEX определяет имя индекса, предложение ON определяет имя таблицы и колонок, для которой и по которым строится индекс, ключевое слово UNIQUE указывает, что индексируемые значения колонок должны быть уникальными для таблицы, т.е. исключается дублирование значений в индексируемой колонке. Таблица должна быть уже создана, и должна содержать определения индексируемых столбцов. Спецификация UNIQUE опциональна, и вы можете также создавать и неуникальные индексы.
Следует помнить, что для многих СУБД целостность первичного ключа поддерживается заданием
Поэтому для завершения процедуры определения первичных ключей CREATE UNIQUE INDEX, как показано ниже:
CREATE UNIQUE INDEX NDXDEPT ON DEPARTAMENT (DEPNO); CREATE UNIQUE INDEX NDXEMPLOYEE ON EMPLOYEE(EMPNO); CREATE UNIQUE INDEX NDXPROJECT ON PROJECT(PROJNO);
Для диалекта SQL СУБД Oracle этого делать не нужно, т.к. она автоматически поддерживает целостность первичного ключа.
После выполнения вышеперечисленных действий задачу определения первичных ключей
При определении NOT NULL ограничением.
Предопределенное значение колонки, равное NULL, означает, что в данный конкретный момент для данной конкретной строки (экземпляра NULL -значения, т.к. пользователи могут иметь проблемы при использовании таких колонок. Примером этой проблемы может служить ситуация, в которой пользователю требуется выполнить соединение двух таблиц по колонкам, имеющим NULL -значения. При выполнении таких соединений любые строки, которые содержат NULL -значения в колонках соединения в любой из таблиц, не будут показаны в результирующей выборке для запроса. Подобная потеря данных может привести к тому, что пользователь получит неправильную выборку на запрос, особенно если ему необходимо видеть все строки хотя бы одной из таблиц.
Примечание. Одним из способов решения определенной выше проблемы является использование
внешних соединений .
При назначении NULL -значений колонкам проектировщику базы данных необходимо принимать во внимание следующие факторы.
NOT NULL, т.к. согласно реляционной теории значения колонок первичного ключа должны быть определены и уникальны для каждого кортежа.NOT NULL, поскольку дочерняя таблица зависит от родительской и внешний ключ родительской не может иметь NULL-значения. Это следует из того, что существование строки дочерней таблицы без соответствующей строки NULL -значений, чтобы показать, что для данной комбинации родительской и дочерних строк в этих таблицах связи нет.SET NULL должны определяться со спецификацией NULL.NOT NULL WITH DEFAULT для колонок с типами данных DATE или TIME, чтобы сохранять текущие даты и текущее время автоматически.NULL -значения только для тех колонок, которые действительно могут иметь неопределенные значения.NOT NULL WITH DEFAULT для всех колонок, которые не подпадают под перечисленные выше правила.Пример. Как можно увидеть ниже, проектировщик базы данных определил, что:
дата поступления служащего в организацию HIREDATEопределена со спецификациейNOT NULL WITH DEFAULT, которая означает, что если на вводе значение колонки не определено, то по умолчанию подставляется текущая дата;номер подразделения DEPNO, номер служащегоEMPNOи номер проектаPROJNOимеют спецификациюNOT NULLкак первичные ключи таблиц;для остальных полей базовых таблиц проектировщик базы данных принял решение разрешить наличие в нихNULL-значений.
CREATE TABLE DEPARTAMENT ( DEPNO integer NOT NULL, DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), PRIMARY KEY (DEPNO) определение первичного ключа ); CREATE TABLE EMPLOYEE ( EMPNO integer NOT NULL, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), PROJNO char(8), JOB char(25), AGE date, HIREDATE date NOT NULL WITH DEFAULT, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), PRIMARY KEY (EMPNO) ); CREATE TABLE PROJECT ( PROJNO char(8) NOT NULL, PNAME char(25), BUDGET dec(9,2), PRIMARY KEY (PROJNO) );
Отношения "многие-ко-многим", как уже упоминалось в предыдущих лекциях, не могут быть в подавляющем большинстве случаев непосредственно реализованы в реляционных базах данных без создания промежуточных таблиц, иначе называемых связывающими таблицами (
Алгоритм задачи разрешения взаимосвязи следующий:
Этот алгоритм решает задачу разрешения отношения "многие-ко-многим". Однако можно подумать об атрибутах (колонках), которые могут существовать у связи (ее представляет связывающая таблица). Такие колонки могут быть помещены в связывающую таблицу. Это могут быть колонки, общие для связываемых таблиц.
Рассмотрим пример. Используемая схема базы данных учебного примера не позволяет использовать одного служащего в нескольких проектах (реализовано отношение "много (служащих) к одному (проекту)"). На практике обычно каждый служащий работает над несколькими проектами (отношение "многие-ко-многим"). Чтобы реализовать такое отношение, необходимо модернизировать структуру физической базы данных. Определим отношение "многие-ко-многим" через создание новой таблицы EMP_PRJ
CREATE TABLE EMP_PRJ ( EMPNO integer NOT NULL, PROJNO char(8) NOT NULL, WORKS number, PRIMARY KEY (EMPNO, PROJNO), FOREIGN KEY (EMPNO) REFERENCES EMPLOYEE, FOREIGN KEY (PROJNO) REFERENCES PROJECT, );
которая будет служить для распределения служащих по проектам. В этой таблице каждому служащему отвечает столько строк, сколько проектов он выполняет. Схема базы данных примет теперь вид как на рис. 9.1. Колонка PROJNO таблицы EMPLOYEE при этом потеряла свой семантический смысл. Ee следует удалить из таблицы EMPLOYEE за ненадобностью.
(рис 9.1) Логическая структура учебной базы данных после разрешения отношения "многие-ко-многим"
Как работать с
CREATE TABLE DEPARTAMENT ( DEPNO integer NOT NULL, DNAME char(20), LOC char(20), MANAGER char(20), PHONE char(15), PRIMARY KEY (DEPNO) определение первичного ключа ); CREATE TABLE EMPLOYEE ( EMPNO integer NOT NULL, ENAME char(25), LNAME char(10), DEPNO int, SSECNO char(10), JOB char(25), AGE date, HIREDATE date NOT NULL WITH DEFAULT, SAL dec(9,2), COMM dec(9,2), FINE dec(9,2), PRIMARY KEY (EMPNO) ); CREATE TABLE PROJECT ( PROJNO char(8) NOT NULL, PNAME char(25), BUDGET dec(9,2), PRIMARY KEY (PROJNO) ); CREATE TABLE EMP_PRJ ( EMPNO integer NOT NULL, PROJNO char(8) NOT NULL, WORKS number, PRIMARY KEY (EMPNO, PROJNO), FOREIGN KEY (EMPNO) REFERENCES EMPLOYEE, FOREIGN KEY (PROJNO) REFERENCES PROJECT );
Таким образом, в результате описанных выше действий был получен скрипт для создания
Дальнейшими задачами проектировщика базы данных будут задачи усовершенствования и доработки разработанного скрипта в следующих направлениях:
Первые три направления деятельности носят опциональный характер и определяются особенностями конкретного ИТ-проекта и вкусами руководителя данного проекта, а также требованиями к базе данных и бизнес-правилами предметной области, если они представлены в исходной документации. Часто, особенно при использовании объектно-ориентированной парадигмы в разработке приложений базы данных, эти три направления деятельности проектировщика базы данных могут быть переданы разработчикам приложений базы данных. Поэтому мы подчеркиваем здесь их необязательный характер. Как может решать такие задачи проектировщик базы данных, будет рассмотрено в других разделах этой лекции. Четвертое направление деятельности очень желательно. Его следует выполнять, если априорно имеются данные о возможном поведении данных в системе во времени. Обычно борьба за производительность относится к задачам обратного влияния, когда становятся известными параметры эксплуатации системы. Это направление деятельности будет рассматриваться в двух последующих лекциях.
Последнее направление деятельности носит обязательный характер для обеспечения функционирования базы данных, эта задача в большей степени является задачей
Ниже приведен типичный синтаксис некоторых команд SQL.
Синтаксис оператора CREATE TABLE:
CREATE TABLE имя_таблицы (имя_колонки тип_данных [NOT NULL | NOT NULL WITH DEFAULT] [, имя колонки ѕ] [PRIMARY KEY (имя_колонки [,имя_колонки ѕ]] [FOREIGN KEY [имя_ключа] (имя_колонки [, имя_колонки ѕ ]) REFERENCES имя_таблицы_родителя [ON DELETE [RESTRICT | CASCADE | SET NULL]]] ) [IN [имя_базы_данных] имя_области_табличного_пространства | IN DATABASE имя_базы_данных] [PCTFREE целочисленная_константа]
Примечание. Здесь и ниже опции операторов SQL, которые не объясняются в настоящем разделе книги, поясняются далее, там, где логика изложения требует их детального обсуждения. Подчеркивание ключевого слова обозначает значение, принятое по умолчанию.
Синтаксис оператора CREATE INDEX:
CREATE [UNIQUE] [CLUSTERED HASHED] INDEX имя_индекса ON имя_таблицы (имя_колонки [ASC | DESC] [, имя_колонки ѕ]) [PCTFREE целочисленная_константа] [SIZE целочисленное_значение [ROWS | BUCKETS]]
В предыдущих разделах мы уже сталкивались с несколькими NOT NULL, и ограничениях в таблицах - PRIMARY KEY, FOREING KEY. В данном разделе мы изучим практически все виды ограничений, которые поддерживаются в реляционных базах данных. Ограничения являются важным инструментом проектировщика базы данных, с помощью которого он поддерживает целостность (strong) базы данных. Их можно использовать для того, чтобы быть уверенным в том, что колонка первичного ключа таблицы является уникальной и всегда содержит значения. Ограничения используются также для
Замечание. Одна из главных концепций реляционной базы данных состоит в том, что всегда целесообразнее заставлять саму базу данных поддерживать свою непротиворечивость, чем заставлять решать эту задачу приложение базы данных. Вопрос о том, что лучше: передавать поддержку ограничений приложениям базы данных или оставлять самой базе данных, - остается все еще открытым.
Ограничения представляют собой способ применения бизнес-правил предметной области на уровне базы данных и гарантируют совместимость вводимых данных с теми, которые уже находятся в таблицах. В реляционной базе данных под ограничением понимается правило (условие), которому должен удовлетворять некоторый элемент в базе данных. Например, условия, которым должны дополнительно удовлетворять значения колонки таблицы в рамках определенного для нее типа данных (т.е. тип данных плюс правило), полностью воплощают концепцию домена в
Как мы видели выше, ограничения могут применяться на уровне колонки (ограничения колонки) или SQL NOT NULL, UNIQUE, CHECK.
| Ограничение | Описание | |
| 1 | CHECK |
гарантирует, что значения находятся в границах специфицированного интервала, задаваемого предикатом |
|---|---|---|
| 2 | DEFAULT |
помещает значение по умолчанию в колонку. Гарантирует, что колонка всегда имеет значение |
| 3 | FOREIN KEY |
гарантирует, что значения существует как значение в колонке первичного ключа другой таблицы. Обеспечивает процедуры удаления дочерних строк при удалении связанных с ней родительских |
| 4 | NOT NULL |
гарантирует, что колонка всегда содержит значение |
| 5 | PRIMARY KEY |
гарантирует, что колонка всегда содержит значение и оно уникально в таблице |
| 6 | UNIQUE |
гарантирует, что значение будет уникальным в таблице |
Ограничение CHECK позволяет выполнять проверку содержимого колонки относительно некоторых условий и списка значений. Она налагается с помощью предложения CHECK. Для добавления этого ограничения нужно после объявления столбца в спецификации колонки определить синтаксическую конструкцию CHECK (предикат). Согласно требованиям стандарта с помощью ключевого слова VALUE в предикате вы ссылаетесь на значение колонки. Но практически во всех диалектах для этой цели используется имя колонки.
Пример. В учебной базе данных в таблице
EMPLOYEEдля сотрудников может указываться признак пола: 0 - мужской, 1 - женский. Бизнес-правило предметной области для значений этого поля может быть сформулировано так:
Лицо, принимаемое на работу, может иметь один из двух допустимых признаков пола.
Тогда
SEX int NOT NULL CHECK (SEX=0 OR SEX=1),
Опция DEFAULT заставляет СУБД размещать значение по умолчанию в колонке, когда кортеж вставляется в таблицу и никакого значения колонки не представлено. Чтобы указать значение по умолчанию, нужно в
Пример. Для нашей учебной базы данных мы могли бы определить значение по умолчанию для числовых колонок в таблице EMPLOYEE:
SAL dec(9,2) DEFAULT(0), COMM dec(9,2) DEFAULT(0), FINE dec(9,2) DEFAULT(0),
NOT NULL ограничение гарантирует, что колонка всегда содержит значения. СУБД не будет разрешать вставлять или обновлять строку таблицы, если в ней существует колонка с ограничением NOT NULL, а данных для этой колонки в добавляемой строке не представлено. Как мы уже видели выше, для колонок первичного ключа это ограничение нужно устанавливать всегда.
Пример. Для нашей учебной базы данных действует правило, что сотрудник всегда должен иметь имя и фамилию. Чтобы удовлетворить этому правилу, нужно определить следующую спецификацию колонок
ENAMEиLNAMEв таблицеEMPLOYEE:
ENAME char(25) NOT NULL, LNAME char(10) NOT NULL,
Иногда ограничение NOT NULL используется вместе с опцией DEFAULT, как это было определено в спецификации колонки HIREDATE (дата приема на работу) в таблице EMPLOYEE:
HIREDATE date NOT NULL WITH DEFAULT,
Мы уже рассматривали вопрос о задании
Ограничение UNIQUE гарантирует уникальность значения данных в колонке. Оно используется, если нужно следить за тем, чтобы значения колонки, не являющейся первичным ключом, были уникальны в таблице. При этом проверяется уникальность всех значений, отличных от NULL.
Пример. В учебной базе данных в таблице
EMPLOYEEиспользуется номер социальной страховки SSECNO, для которого бизнес-правило состоит в том, что для каждой персоны, если она имеет такой номер, он должен быть уникальным. Установить уникальность этих номеров можно следующей спецификацией колонки:
SSECNO char(10) UNIQUE,
Ограничение UNIQUE можно определить также в конце команды CREATE TABLE в следующей синтаксической форме: UNIQUE (SSECNO).
Ограничения задаются в спецификациях колонки или спецификациях ключей при создании таблицы в командах SQL CREATE TABLE или налагаются после создания таблицы в командах SQL . Как добавить ограничения в таблицу с помощью команды CREATE TABLE, мы уже знаем. Чтобы добавить ограничения с помощью команды , можно поступать следующим образом.
Пример. Для нашей учебной базы данных мы могли бы не определять первичный ключ в таблице
EMPLOYEEв командеCREATE TABLEи после нее выполнить команду
ALTER TABLE EMPLOYEE PRIMARY KEY (EMPNO);
Аналогично, мы могли бы установить ограничение внешнего ключа в таблице EMP_PRJ следующим образом:
CREATE TABLE EMP_PRJ ( EMPNO integer NOT NULL, PROJNO char(8) NOT NULL, WORKS number, PRIMARY KEY (EMPNO, PROJNO), ); ALTER TABLE EMP_PRJ FOREING KEY (EMPNO) REFERENCES EMPLOYEE ON DELETE RESTRICT, FOREING KEY (PROJNO) REFERENCES PROJECT ON DELETE RESTRICT;
Чтобы удалять ограничения первичного и внешнего ключей, можно использовать команду в синтаксической форме
ALTER TABLE EMPLOYEE DROP PRIMARY KEY (EMPNO);
В СУБД Oracle 9i для создания :
ALTER TABLE имя_таблицы ADD CONSTRAINTS ограничение TYPE(колонка);
а для удаления
ALTER TABLE имя_таблицы DROP CONSTRAINTS ограничение.
Кроме этого, в СУБД Oracle 8i можно блокировать и деблокировать действие ограничений с помощью опций DISABLE и ENABLE команды , как показано в примере ниже:
ALTER TABLE EMPLOYEE DISABLE PRIMARY KEY; ALTER TABLE EMPLOYEE ENABLE PRIMARY KEY;
После использования опции DISABLE ограничение становится неактивным, но его определение остается в словаре базы данных. Вы можете вернуть ENABLE. Использование опции DROP полностью удаляет ограничение из базы данных (и словаря базы данных также).
В реляционной теории концепция
Допустимость ссылки еще не означает ее корректность. Так, в учебной базе данных вы можете приписать служащему в таблице EMPLOYEE несуществующий номер отдела. Однако значение номера отдела в этой таблице должно быть согласовано с соответствующим значением в таблице DEPARTAMENT. Поддержка DEPARTAMENT. При этом вставка служащего с неправильным номером отдела будет заблокирована. Однако правильность списка сотрудников отдела не контролируется. Допустимая ссылка еще не означает ее правильность.
Иными словами,
Такие ограничения (в виде бизнес-правил) определяются при
В настоящее время большинство промышленных реляционных СУБД имеют встроенный механизм
Механизм
Понятие первичного ключа как уникального идентификатора кортежа отношения уже обсуждалось выше. Здесь нас интересует другой аспект данного понятия. А именно - то, что первичный ключ может гарантировать целостность данных. Если первичный ключ корректно используется, все
Поддержка
Замечание. В СУБД Oracle 9i первичный индекс создается автоматически.
В конкретных реализациях СУБД существуют дополнительные ограничения на определение первичного ключа. Так, в SQLBase первичный ключ не может включать более 16 колонок, общая длина первичного ключа не может превышать 255 байт, нельзя использовать колонки типа LONG/LONG VARCHAR, в самоссылающихся строках значение первичного ключа невозможно модифицировать.
Внешний ключ представляет собой ссылку на первичный ключ в данной или другой таблице, т.е. один или несколько атрибутов отношения, которые содержат первичный ключ другого отношения. Примером внешнего ключа является номер отдела DEPNO в таблице EMPLOYEE нашей учебной базы данных.
Из определения следует, что внешний ключ может быть создан только после создания соответствующего первичного ключа (и первичного индекса). Внешнему ключу обычно назначается специальное имя. Внешние ключи имеют следующие свойства:
Поддержка
В SQLBase существуют ограничения на определение внешнего ключа:
В других СУБД ограничения на определение внешнего ключа носят аналогичный характер.
Первичный и соответствующий ему внешний ключ позволяют реализовать отношение "родитель-потомок" (parent/child
Таблица реляционной базы данных, содержащая первичный ключ, называется таблицей-родителем (parent table) или DEPARTAMENT учебной базы данных является таблицей-родителем для таблицы EMPLOYEE.
Таблица базы данных может не иметь ни родителей, ни потомков. Такие таблицы называются независимыми таблицами (
Отношение "родитель-потомок" между таблицами реализуется через атрибуты-ключи соответствующих строк. Строка, принадлежащая
Совсем необязательно, чтобы каждая строка таблицы-родителя была родительской строкой. Аналогично, если строка в таблице-потомке имеет нуль-значение внешнего ключа, то она не будет строкой-потомком.
Отношение "родитель-потомок" между двумя таблицами отражает взаимосвязь по включению на доменах соответствующих атрибутов. Однако, таблица может реализовать отношение иерархического подчинения в самой себе. Примером такой таблицы может стать
Таблицы называются связанными по удалению (delete-connected tables), если удаление строки в одной таблице влияет на состояние строк в другой таблице. Так, если в таблице DEPARTAMENT удалить отдел (в связи с его ликвидацией), то в таблице EMPLOYEE необходимо либо удалить некоторых служащих этого отдела (уволились), либо изменить у них номер отдела (переведены в другой). Любая таблица, которая участвует в операции удаления при ограничениях
Также ясно, что самоссылающаяся таблица является связанной по удалению сама с собой,
Для создания таблиц с поддержкой ограничений CREATE TABLE и команда . Таким образом, вы имеете два основных способа для
PRIMARY KEY и FOREIGN KEY команды CREATE TABLE ;ADD/DROP PRIMARY KEY и ADD/DROP FOREIGN KEY команды ALTER TABLE .В предыдущих разделах уже было показано использование предложения PRIMARY KEY команды CREATE TABLE. Пример использования предложения команды CREATE TABLE продемонстрируем на примере создания таблицы для иерархии "руководитель-подчиненный":
CREATE TABLE MANAGEMENT ( MANAGNO INT NOT NULL, EMPNO INT, JOB INT, PRIMARY KEY (MANAGNO), FOREIGN KEY fnkey (EMPNO) REFERENCES EMPLOYEE ON DELETE CASCADE); CREATE UNIQUE INDEX ndxmng ON MANAGEMENT(MANAGNO);
fnkey - имя внешнего ключа, предложение REFERENCES, связанное с предложением , определяет имя таблицы-родителя, предложение ON DELETE определяет правило удаления записей в связанных таблицах. Каждое правило удаления соответствует определенной взаимосвязи между объектами реляционной базы данных (т. е. предметной области).
Правила удаления используются только в определении внешнего ключа. Обычно СУБД в соответствии со стандартом SQL поддерживает три правила:
CASCADE - сначала удаляется заданная строка в RESTRICT - строка может быть удалена, если никакие другие строки не зависят от нее, в противном случае удаления не происходит;SET NULL - для любого удаляемого первичного ключа соответствующее ему значение внешнего ключа дочерней строки принимает нуль-значение.Для самоссылающихся таблиц используется только правило CASCADE. Правило RESTRICT препятствует удалению строки в таблице-родителе, если ей соответствуют какая-либо строка в таблице-потомке. Правило CASCADE определяет, что, когда строка в таблице-родителе удаляется, то все связанные с ней строки в таблице-потомке автоматически должны быть удалены. Правило определяет, что, когда строка в
Применение команды продемонстрируем на примере создания отношения "родитель-потомок" для таблиц DEPARTAMENT и EMPLOYEE учебной базы данных. Первичные ключи и индексы для этих таблиц уже созданы. Создадим внешние ключи (в таблицу DEPARTAMENT должна быть добавлена колонка EMPNO ).
ALTER TABLE DEPARTAMENT FOREIGN KEY EMP_DEP (EMPNO) REFERENCES EMPLOYEE ON DELETE RESTRICT;
Для того, чтобы удалить первичный или внешний ключ таблицы, необходимо использовать предложение DROP команды .
Естественно, что ограничения
Для команды INSERT предусмотрены следующие правила:
NOT NULL значение атрибута внешнего ключа должно соответствовать значению атрибута первичного ключа в таблице-родителе;Для команды UPDATE предусмотрены следующие правила:
Попытка обновить первичный ключ UPDATE.
Правила для команды DELETE сообщают СУБД, что ей делать, когда пользователь пытается удалить строку в таблице-родителе. Отметим также, что в командах удаления нельзя использовать
Применение команды DROP в условиях ограничений
Использование ограничений EMPLOYEE содержит колонку DEPNO (внешний ключ, содержащий ссылку на таблицу DEPARTAMENT ). Если добавить в таблицу EMPLOYEE колонку MNGR, которая определяет руководителя каждого служащего, а в таблицу DEPARTAMENT - колонку с номером руководителя MRGNO, то мы получим пример ссылочного цикла (при определении
Такой вид циклической связи порождает проблемы для операций манипулирования данными. Допустим, что на работу принят служащий, который должен руководить вновь созданным отделом 100. Последовательное выполнение операторов INSERT будет неуспешным (строка в дочерней таблице EMPLOYEE ссылается на отдел, которого еще нет, и такого менеджера еще не существует).
INSERT INTO EMPLOYEE (EMPNO,ENAME,LNAME,DEPNO,
JOB,AGE,HIREDATE,SAL,COMM,FINE,MNGR)
VALUES(4000,"Анисимов","Виктор",100,"Менеджер",,2500000,,,NULL);
INSERT INTO DEPARTAMENT
(DEPNO, DNAME, LOC, MANAGER, MRGNO,PHONE)
VALUES (100,'Маркетинг','Москва', 'Анисимов', 4000,1352519);
Операция добавления в базу данных записей, связанных с организацией нового отдела и прихода его руководителя, при
INSERT INTO EMPLOYEE (EMPNO,ENAME,LNAME,DEPNO,
JOB,AGE,HIREDATE,SAL,COMM,FINE,MNGR)
VALUES(4000, "Анисимов","Виктор",NULL, "Менеджер",,2500000,,,NULL);
INSERT INTO DEPARTAMENT
(DEPNO, DNAME, LOC, MANAGER, MRGNO,PHONE)
VALUES (100,'Маркетинг','Москва', 'Анисимов', 4000,1352519);
UPDATE EMPLOYEE
SET DEPNO=100
WHERE EMPNO=4000;
Аналогичным образом могут, при наличии ссылочных циклов, возникать проблемы с операцией удаления кортежей в родительской и
Более подробное описание работы с ограничениями
В этом разделе мы изучили ограничения, которые поддерживаются в реляционной базе данных средствами СУБД. Такие ограничения представляют встроенные в СУБД механизмы обеспечения целостности данных и
Ниже приведен типичный синтаксис команды .
Типичный синтаксис команды (без учета
ALTER TABLE имя_таблицы DROP [имя_колонки [,имя_колонки ѕ]] ADD имя_колонки тип_данных [(размер)] [NOT NULL | NOT NULL WITH DEFAULT] RENAME имя_колонки новое_имя | TABLE новое_имя MODIFY имя_колонки тип_данных [(размер)] [NULL | NOT NULL | NOT NULL WITH DEFAULT]
СУБД предоставляет вам возможность создавать представления или так называемые
Примечание. Далее в тексте термины "представление" и "
виртуальная таблица " будут употребляться на равных правах.
Для создания виртуальных таблиц в SQL предназначена команда . Пусть вам требуется регулярно просматривать списки служащих по отделам. Тогда вы можете использовать
CREATE VIEW EMPLIST AS SELECT DEPNO, EMPNO, ENAME, JOB FROM EMPLOYEE GROOP BY DEPNO, EMPNO, ENAME, JOB;
Как видите, SELECT. Как известно, результат выполнения команды SELECT является таблицей. GROUP BY, иногда называется групповым представлением (grouped view)
Как только промежуточная таблица получает имя, к ней можно делать запрос. Например, выполнить команду
SELECT * FROM EMPLIST WHERE DEPNO=10;
которая дает список сотрудников 10-го подразделения.
Однако во многих реализациях SQL представления имеют сильные ограничения на выполнение операций обновления данных над ними. Некоторые СУБД не разрешают в определении представления использовать предложение ORDER BY. В некоторых диалектах SQL недопустимо выполнение обновлений на виртуальных таблицах, определенных на нескольких GROUP BY, HAVING, опцию и функции агрегирования. Такие представления используются только для чтения. Например, в СУБД SQLBase представление используется только для чтения (read-only view), если в определяющей команде SELECT:
FROM задействует имена более одной таблицы или представления;DISTINCT ;GROUP BY ;HAVING ;Иногда запрещается использовать и
В противном случае представление считается обновляемым представлением (updatable view). Для обновляемых представлений предусмотрена опция WITH CHECK OPTION. Когда она указана, любая вставка и обновление через данное представление будет выполняться только, если представление отвечает своему определению (данные в таблице могут быть изменены непосредственно). В противном случае такой проверки не делается. Если представление предназначено только для чтения или применяет
Команда с такими же ограничениями также выполнима на виртуальных таблицах.
Если вам необходимо работать с несколькими таблицами как с одной, вы можете создать
CREATE VIEW PERSPROJ AS SELECT ENAME, JOB, PNAME FROM EMPLOYEE, PROJECT WHERE EMPLOYEE.PROJNO=PROJECT.PROJNO;
Выполняя команду
SELECT * FROM PERSPROJ;
вы получите необходимую вам информацию. При этом вам не нужно помнить, что данные хранятся в двух таблицах. Даже если будет изменена структура базы данных, не затрагивающая колонки из виртуальной таблицы, вы этого не заметите.
Можно выполнять и более сложные запросы на виртуальных таблицах. Допустим, что вам нужен список руководителей по проектам, тогда вы можете выполнить
SELECT ENAME, PNAME FROM PERSPROJ WHERE JOB='руководитель';
С виртуальными таблицами используется предложение WITH CHECK OPTION. При этом каждая вставка или обновление будет проверяться на соответствие определению виртуальной таблицы и будет отвергаться, если такого соответствия не будет. В противном случае такой проверки не делается.
Пусть вам нужно иметь информацию о текущих проектах. Тогда можно определить START_DATE в таблице PROJECT и установив его значения) как
CREATE VIEW CURPROJ AS SELECT * FROM PROJECT WHERE START_DATE < SYSDATE WITH CHECK OPTION;
Колонка START_DATE при обновлении будет проверяться на соответствие текущей дате. Это предложение справедливо только для обновления данных в колонках WITH CHECK OPTION не должно указываться.
Как вы могли видеть,
Рассмотрим пример из предыдущего раздела. Примененная схема базы данных учебного примера не позволяет использовать одного служащего в нескольких проектах (реализовано отношение "много (служащих) к одному (проекту)"). На практике обычно каждый служащий работает над несколькими проектами (отношение "многие-ко-многим"). Чтобы реализовать такое отношение, необходимо модернизировать структуру базы данных. При этом все ранее разработанные приложения и PREM:
CREATE TABLE PREM ( EMPNO integer, PROJNO char(8), WORKS number);
которая будет служить для распределения служащих по проектам. В этой таблице каждому служащему отвечает столько строк, сколько проектов он выполняет. Колонка PROJNO таблицы EMPLOYEE при этом потеряла свой семантический смысл. Удалим эти данные:
UPDATE EMPLOYEE SET PROJNO=NULL;
При этом мы уже не можем пользоваться виртуальной таблицей PERSPROJ, которая использует эту колонку для соединения таблиц EMPLOYEE и PROJECT. Чтобы для пользователя ничего не изменилось, следует переопределить PERSPROJ. Для этого удалим ее с помощью команды SQL DROP. Команда DROP является в SQL универсальной командой для удаления объектов реляционной базы данных: вы только должны определить, что вы хотите удалить: TABLE, VIEW или иной объект.
Удалим определение неподходящей виртуальной таблицы:
DROP VIEW PERSPROJ;
Создадим новую
CREATE VIEW PERSPROJ AS SELECT ENAME, JOB, PNAME FROM EMPLOYEE, PROJECT, PREM WHERE EMPLOYEE.EMPNO=PREM.EMPNO AND PREM.PROJNO=PROJECT.PROJNO;
Колонку PROJNO в таблице EMPLOYEE следует удалить за ненадобностью:
ALTER TABLE EMPLOYEE DROP PROJNO;
Вы видите, как легко изменить структуру базы данных, не внося слишком больших изменений в ваши приложения и используемые запросы (на виртуальных таблицах). Это объясняется тем, что SQL является непроцедурным языком, т.е. ваши программы и запросы не привязываются к структуре базы данных. За счет модификации виртуальных таблиц вы можете скрыть фактические изменения структуры базы данных от пользователя. Рассмотренный выше пример иллюстрирует основные моменты реализации концепции независимости данных в реляционных базах данных.
Представления (
Концепция представления особенно важна, когда требуется извлекать информацию из нескольких отношений. Во-первых, она является средством формирования пользователем своей виртуальной (внешней) схемы базы данных. Во-вторых, это средство формирования производных или выводимых атрибутов отношений базы данных, то есть таких атрибутов, которые непосредственно не хранятся в базе данных. Представление можно трактовать как
Обратимся к примеру с футболом. Пусть имеется некоторая база данных, которая содержит всю информацию о чемпионате мира по футболу. Допустим, что вас интересует информация о стадионах и об играх, закончившихся с определенной разностью забитых и пропущенных мячей. Тогда вы можете первоначально определить представление как
CREATE VIEW СТАДРАЗН (стад, разн_мячей ) AS SELECT стадион, голыА - голыВ FROM ИГРЫ, РАЗМ_СТАДИОНОВ WHERE ИГРЫ.год = РАЗМ_СТАДИОНОВ.год AND ИГРЫ.группа = 2 АND РАЗМ_СТАДИОНОВ.группа=2 АND ИГРЫ.игра=РАЗМ_СТАДИОНОВ.игра
В этом примере также демонстрируется, как определять производные колонки в представлении.
Теперь вы можете выполнить запрос к виртуальной таблице, такой, чтобы получить ответ на вопрос: выдать все стадионы, на которых игры закончились с разностью мячей больше 4. Команда языка SQL в этом случае тривиальна:
SELECT стад FROM СТАДРАЗН WHERE разн_мячей > 4;
Таким образом, представление в алгебре отношений является операцией наименования промежуточных результатов.
Синоним есть другое имя для таблицы или представления. Синонимы используются для того, чтобы сделать базу данных более дружественной для пользователя. Это означает, что объектам базы данных, которые попадают в сферу внимания пользователей, назначаются альтернативные, длинные имена в терминах предметной области базы данных. Такие имена более понятны неподготовленным
Задача назначения синонимов объектам базы данных является задачей
Синоним по определению может быть общим для всех PUBLIC ) или принадлежать пользователю (USER), который его создал. Опция PUBLIC позволяет обращаться к таблице с помощью синонима без уточнения имени таблицы именем владельца. Чтобы создать или удалить синоним PUBLIC, необходимо либо быть владельцем таблицы, либо иметь привилегии пользователей SYS или SYSTEM (Oracle). (Для СУБД SQLBase
Пример. Для нашей учебной базы данных вы можете создать синоним EMP для таблицы
EPMPLOYEEс помощью следующей команды:
CREATE PUBLIC SYNONYN EMP FOR EPMPLOYEE;
Или для пользователя SYS:
CREATE SYNONYN SYS.EMPL FOR EPMPLOYEE;
Чтобы удалить синоним EMP таблицы EPMPLOYEE, необходимо использовать команду
DROP PUBLIC SYNONYN EMP;
При обсуждении представлений мы уже касались понятия внешней схемы. В этом подразделе мы остановимся на этом понятии более подробно. Создание внешней схемы является желательным, но совсем не обязательным действием проектировщика данных.
В архитектуре трех схем ANSI/SPARC внешняя схема используется для изоляции требований к данным пользователей и приложений от физического размещения данных. Такая изоляция по определению делает пользователей независимыми от аспектов
В настоящее время стандарт SQL, так же как и большинство промышленных СУБД, не говоря уже об экспериментальных СУБД, обеспечивают поддержку внешней схемы ограниченно. Основным способом изоляции требований пользователей к данным от особенностей их физического хранения является механизм реляционных представлений, который мы обсуждали выше.
Приведем примеры, когда изменения на уровне физической организации базы данных могут быть скрыты от пользователей с помощью представлений.
Создание внешней схемы является в большей степени задачей
Однако, если руководителем ИТ-проекта принято решение о разработке внешней схемы, проектировщик должен создать первоначальный вариант внешней схемы.
Для того чтобы создать внешнюю схему для новой базы данных, проектировщику базы данных необходимо начать с создания так называемых зеркальных представлений. Такое представление разрабатывается для каждой базовой таблицы
Дополнительные представления могут быть созданы для приложений, которые выполняют так называемые типовые запросы к базам данных. Под типовым запросом здесь понимается запрос, который выполняется с высокой частотой использования либо одним пользователем, либо группой пользователей. Такое представление проектировщик базы данных может разработать, если требования к обработке данных задокументированы в спецификациях к базе данных.
Представления для эпизодических
Создавать внешнюю схему наиболее удобно параллельно с внутренней, по мере того как создаются
Пример. Для нашей учебной базы данных первоначальная внешняя схема может выглядеть следующим образом:
CREATE VIEW DEPARTAMENT_V AS SELECT DEPNO, DNAME, LOC, MANAGER, PHONE FROM DEPARTAMENT; CREATE VIEW EMPLOYEE_V AS SELECT EMPNO, ENAME, LNAME, DEPNO, SSECNO, JOB, AGE, HIREDATE, SAL, COMM, FINE FROM EMPLOYEE; CREATE VIEW PROJECT_V AS SELECT PROJNO, PNAME, BUDGET FROM PROJECT; CREATE VIEW PERSPROJ AS SELECT ENAME, JOB, PNAME FROM EMPLOYEE, PROJECT, EMPL_PROJ WHERE EMPLOYEE.EMPNO= EMPL_PROJ.EMPNO AND EMPL_PROJ.PROJNO=PROJECT.PROJNO;
Проектировщик базы данных в данном случае решил создать зеркальные представления для _V в именах представлений, для того чтобы указать, что эти представления зеркально отображают поля базовой таблицы с именем без суффикса.
Кроме этого, он добавил представление, позволяющее получать информацию о служащих и выполняемых ими проектах, которая включает связывающую таблицу для этого отношения со степенью связи "многие-ко-многим".
В этом разделе мы рассмотрели механизм представлений реляционной базы данных. Представления как объекты базы данных занимают немного физического пространства в словаре базы данных, но обеспечивают функциональность базы данных на уровне таблиц. Помимо прочего они позволяют скрывать от пользователей информацию о физической структуре таблиц базы данных, что повышает безопасность эксплуатации базы данных в целом. Представления являются в реляционных базах данных основным механизмом для построения внешней схемы базы данных.
Ниже приведены рекомендации проектировщикам баз данных по созданию представлений в типичной реляционной базе данных.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.