Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретические основы реляционных баз данных. Учебное пособие.pdf
Скачиваний:
0
Добавлен:
15.08.2026
Размер:
936 Кб
Скачать

- 48 -

отклонена. Наиболее общим значением по умолчанию является NULL. Это значение по умолчанию для любого столбца, которому не было дано ограничение NOT NULL или который имеет другое значение по умолчанию. Значение DEFAULT (ПО УМОЛЧАНИЮ) указывается в команде CREATE TABLE тем же способом, что и ограничение столбца.

Предположим, что нам чаще всего требуется вводить информацию о студентах группы 342 женского пола. Тогда следует создать таблицу следующим образом:

CREATE TABLE IF NOT EXISTS students ( family varchar(20),

name varchar(15),

stgroup varchar(5) DEFAULT '342', gpa numeric(3,2),

sex char(1) DEFAULT 'ж'); CREATE TABLE

Теперь после ввода данных

INSERT INTO nstudents (family, name)

VALUES ('Попова','Наталья');

INSERT

0 1

 

 

 

 

 

SELECT

* FROM nstudents ;

 

 

family

|

name

|

stgroup | gpa | sex

--------

 

+---------

 

+

---------

+-----

+-----

Попова

|

Наталья |

342

|

| ж

(1 row)

Мы видим, что группе и полу были присвоены значения по умолчанию, а средний балл не принял никакого значения.

2.9. Поддержка целостности данных

Когда все значения в поле одной таблицы представлены в поле другой таблицы, мы говорим, что первое поле ссылается на второе. Это указывает на прямую связь между значениями двух полей. Например, каждый из студентов в таблице students имеет поле stgroup, которое указывает на группу, определенную в таблице stgroups. Для каждого студента в таблице students имеется одна, и только одна группа.

Когда одно поле в таблице ссылается на другое, оно называется внешним ключом, а поле, на которое оно ссылается, называется родительским ключом. Так что поле stgroup таблицы students это внешний ключ, а поле stgroup, на которое оно ссылается в таблице stgroups, это родительский ключ.

- 49 -

Имена внешнего ключа и родительского ключа необязательно должны быть одинаковыми, это только соглашение, которому мы следуем, чтобы сделать соединение более понятным.

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

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

Для ввода ограничения целостности следует использовать фразу FOREIGN KEY в команде CREATE TABLE (или ALTER TABLE), содержащей поле, которое желательно объявить внешним ключом. Здесь же даётся имя родительскому ключу, на которое вы будете ссылаться внутри ограничения FOREIGN KEY.

Синтаксис ограничения таблицы FOREIGN KEY:

FOREIGN KEY <column list>

REFERENCES <pktable> [<column list>]

Первый список столбцов состоит из одного или более столбцов таблицы, которые разделены запятыми и будут созданы или изменены этой командой.

Pktable - это таблица, содержащая родительский ключ. Она может быть таблицей, которая создаётся или изменяется текущей командой.

Второй список столбцов - это список столбцов, которые будут составлять родительский ключ.

Списки двух столбцов должны быть совместимы, т.е.:

*Они должны иметь одинаковое число столбцов.

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

2.9.1. Первичные ключи

Ограничение первичного ключа означает, что образующий его столбец или группа столбцов может быть уникальным идентификатором строк в таблице. Для этого требуется, чтобы значения были одновременно уникальными и отличными от NULL. Таким образом, таблицы со следующими двумя определениями будут принимать одинаковые данные:

- 50 -

CREATE TABLE students (

family varchar(20) UNIQUE NOT NULL, name varchar(15),

stgroup varchar(5), gpa numeric(3,2), sex char(1));

CREATE TABLE

CREATE TABLE students (

family varchar(20) PRIMARY KEY, name varchar(15),

stgroup varchar(5), gpa numeric(3,2), sex char(1));

CREATE TABLE

Первичные ключи могут включать несколько столбцов; синтаксис похож на запись ограничений уникальности:

CREATE TABLE nstudents ( family varchar(20), name varchar(15), stgroup varchar(5),

gpa numeric(3,2), sex char(1),

PRIMARY KEY (family, name)); CREATE TABLE

При создании первичного ключа все столбцы, которые в него входят, становятся автоматически NOT NULL.

В нашем примере продемонстрируем ограничение целостности на примере таблиц студентов и групп, когда студент может обучаться только в одной группе:

CREATE TABLE stgroups (

stgroup varchar(5) PRIMARY KEY, department char(7),

curator varchar(15)); CREATE TABLE

CREATE TABLE nstudents ( family varchar(20), name varchar(15),

stgroup varchar(5) REFERENCES stgroups(stgroup), gpa numeric(3,2),

sex char(1),

PRIMARY KEY (family, name)); CREATE TABLE

- 51 -

Теперь у нас таблица stgroups — главная, а таблица students — подчиненная, в которой имеется ссылка на первичный ключ главной таблицы stgroup. Поскольку ссылка всегда осуществляется на первичный ключ главной таблицы, то имя внешнего ключа можно не указывать и пользоваться сокращенной формой записи, в которой имеется ссылка только на главную таблицу:

university=# CREATE TABLE nstudents ( family varchar(20),

name varchar(15),

stgroup varchar(5) REFERENCES stgroups, gpa numeric(3,2),

sex char(1),

PRIMARY KEY (family, name)); CREATE TABLE

Теперь попытка ввести студента из группы, которой нет в главной таблице, приведет к ошибке:

INSERT INTO nstudents

VALUES ('Нефедов','Максим','347',4.39,'м');

ERROR: insert or update on table "nstudents" violates foreign key constraint "nstudents_stgroup_fkey"

DETAIL: Key (stgroup)=(347) is not present in table

"stgroups".

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

2.9.2. Пользовательские представления

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

CREATE VIEW students342

AS SELECT * FROM students

WHERE stgroup= '342';

CREATE VIEW

SELECT * FROM students342;

 

 

 

- 52 -

 

 

 

family

| name

|

stgroup |

gpa

| sex

--------------

+--------

+

---------

+

------

+-----

Балашов

| Андрей |

342

|

5.00

| м

Катеринченко

| Андрей |

342

|

4.59

| м

Никулкин

| Сергей |

342

|

4.79

| м

Фахрудинова

| Тамара |

342

|

4.12

| ж

(4 rows)

 

 

 

 

 

 

Когда с помощью команды SELECT выбираются все строки из представления, выполняется запрос, содержащийся в определении представления. При наличии предиката (в нашем случае это WHERE stgroup= '342') мы можем увидеть только те строки, которые этому предикату удовлетворяют. Представления позволяют очень дозированно и в удобной форме предоставлять данные конечному пользователю. Например, мы можем скрыть от пользователя средний балл студента, если в нем для пользователя нет необходимости:

CREATE VIEW v_students

AS SELECT family, name, stgroup, sex

FROM students;

 

 

CREATE VIEW

 

 

 

SELECT * FROM v_students;

 

family

| name

| stgroup | sex

--------------

+---------

+---------

+-----

Балашов

| Андрей

| 342

| м

Катеринченко

| Андрей

| 342

| м

Колычева

| Лия

| 349

| ж

Малин

| Сергей

| 345

| м

Никулкин

| Сергей

| 342

| м

Фахрудинова

| Тамара

| 342

| ж

Чертков

| Максим

| 344

| м

Дубоделов

| Андрей

| 345

| м

Макаркина

| Надежда

| 344

| ж

Нефедов

| Максим

| 347

| м

(10 rows)

 

 

 

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

Пользовательские представления можно модифицировать. В примере ниже мы переводим студента в группу 342. Следует отметить, что запрос на изменение данных реально адресуется к физической таблице students, но через представление v_students.

UPDATE v_students

SET stgroup = 342

WHERE family = 'Колычева'; UPDATE 1

- 53 -

Групповые представления содержат предложение GROUP BY и позволяют предварительно агрегировать данные и не предоставлять пользователю определенную информацию. В примере мы группируем студентов по группам, определяем количество студентов и средний балл в каждой группе, но скрываем персональные данные (фамилию, имя, пол):

CREATE VIEW v_students AS SELECT stgroup,

AVG(gpa) AS avr_gpa ,COUNT(stgroup)

FROM students GROUP BY stgroup ORDER BY stgroup;

CREATE VIEW

 

 

 

SELECT *

FROM v_students ;

 

 

stgroup

|

avr_gpa

| count

---------

+--------------------

 

+

-------

342

| 4.5760000000000000 |

5

344

| 4.3100000000000000 |

1

345

| 4.8700000000000000 |

1

346

| 4.0400000000000000 |

1

347

| 4.3900000000000000 |

1

(5 rows)

 

 

 

 

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

CREATE VIEW v_students

AS SELECT family, name, gpa ,s.stgroup, department

FROM students s, stgroups g

 

WHERE s.stgroup=g.stgroup;

 

CREATE VIEW

 

 

 

 

 

SELECT * FROM v_students

;

 

 

family

| name

|

gpa

| stgroup | department

--------------

+--------

+

------

+---------

+------------

Балашов

| Андрей |

5.00

| 342

| ЭВМ

Катеринченко

| Андрей |

4.59

| 342

| ЭВМ

Малин

| Сергей |

4.87

| 345

| ВПМ

Никулкин

| Сергей |

4.79

| 342

| ЭВМ

Фахрудинова

| Тамара |

4.12

| 342

| ЭВМ

Чертков

| Максим |

4.31

| 344

| САПР

Колычева

| Лия

|

4.38

| 342

| ЭВМ

(7 rows)

 

 

 

 

 

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]