Самоучитель по SQL-сервер в Linux



Таблицы в PostgreSQL

Многие программисты (особенно обладающие опытом работы с другими реляционными СУБД на базе SQL) хорошо знакомы с общими концепциями реляционных баз данных, рассмотренными в этой главе. Тем не менее в разных РСУ БД используются разные механизмы работы с таблицами на системном уровне. В этом разделе более подробно описана реализация таблиц в PostgreSQL.

Системные поля

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

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

Таблица 3.25. Системные поля

Поле

Описание

old 4-байтовый уникальный идентификатор объекта записи. В пределах одной таблицы значения end никогда не повторяются

tableoid

Идентификатор объекта таблицы, содержащей запись. Имя таблицы связывается с идентификатором в системной таблице рд class

xmin

Идентификатор транзакции вставки для кортежа

cmin

Идентификатор команды, ассоциированной с транзакцией вставки для кортежа

xmax

Идентификатор транзакции удаления для кортежа. Для видимых (не удаленных) кортежей равен нулю

cmax

Идентификатор команды, ассоциированной с транзакцией удаления для кортежа. По аналогии с xmax равен нулю для видимых кортежей

ctid

Идентификатор, описывающий физическое местонахождение кортежа в базе данных. Поле ctid содержит пару чисел: номер блока и индекс кортежа в блоке

Идентификаторы объектов

Как было сказано в подразделе «Таблицы» раздела «Знакомство с реляционными базами данных», база данных содержит таблицы, а каждая таблица содержит хотя бы одно именованное поле. Таблица может содержать записи данных, но их наличие не является обязательным. Каждое поле записи, хранящейся в таблице, содержит некоторые данные или NULL.

Один из вопросов, которые приходится решать при операциях с базами данных, — как различить две записи с одинаковыми значениями полей? Для этого в PostgreSQL предусмотрены идентификаторы объектов (object identifiers, OID), никальные в пределах таблицы. Иначе говоря, таблица никогда не содержит записи одинаковыми идентификаторами OID. Таким образом, даже если содержимое пользовательских полей двух записей полностью совпадает, на программном уровне записи можно различить по значению OID. Пример приведен в листинге 3.31.

Листинг 3.31. Идентификация записей по OID

3Stdb=# SELECT * FROM my_list;

todos
----------------------------------
Correct redundancies In my_list.

Correct redundancies in my_list.

(1 rows)

testdb=# SELECT *. old FROM my_list:

todos | old
----------------------------------------
Correct redundancies in my list. | 3391263

Correct redundancies In my list. | 3391264

( 2 rows)

testdb=# DELETE FROM my_list

testdb-# WHERE old = 3391264;

DELETE 1

testdb=# SELECT *.oid FROM my_list;

todos old
----------------------------------------------

Correct redundancies in my list. | 3391263

(1 row)

Предварительное планирование

Прежде чем переходить к непосредственному созданию таблиц, желательно выде-ить немного времени на предварительное планирование объектов базы данных, также на выбор имени, типа и смысла каждого поля в таблице. В результате пла-ирования схема выбора имен становится более стройной и последовательной, это, в свою очередь, приводит к появлению более наглядных и «вразумительных» команд и запросов.
Кроме перечисленных семантических факторов (имена, типы и смысл полей), еобходимо проследить за четким установлением связей между таблицами. Проек-ирование связей является важной частью процесса проектирования таблиц, по-кольку любые ошибки в этой области — как дублирование больших объемов дан-ых, так и случайное исключение важных данных из таблиц — являются крайне ежелательными.
Вернемся к таблице books базы данных booktown, структура которой приведена табл. 3.1. В полях каждой записи хранится внутренний код книги, название, код втора и код темы. Обратите внимание: вместо полного имени автора и текстового писания темы в таблице хранятся простые целочисленные коды, используемые ля связи с двумя другими таблицами: authors и subjects. Содержимое этих таблиц астично иллюстрируют табл. 3.26 и 3.27.

Таблица 3.26. Таблица authors

id

last_name

first_name

1809

Geisel

Theodor Seuss

illl

Denham

Ariel

15990

Bourgeois

Paulette

2031

Brown

Margaret Wise

25041

Margery Williams

Bianco

16

Alcoa

Louisa May

115

Poe

Edgar Allen

Таблица 3.27. Таблица subjects

id

subject

location

1809

Arts

Creativity St

1111

Children's Books

Kids Ct

15990

Classics

Academic Rd

2031

Computers

Productivity Ave

25041

Drama

Main St

16

Horror

Black Raven Dr

115

Science Fiction

Main St

Вынесение данных об авторе и теме из таблицы books повышает эффективность хранения данных. Если в таблице имеются данные о нескольких книгах, относящихся к одной теме, то вместо нескольких экземпляров полных данных, связанных с темой, в таблице будут храниться только значения subjected. Кроме того, это упрощает модификацию данных, связанных с темой книги (например, информации о размещении этих книг на полках магазина). Такие данные достаточно один раз изменить в одной небольшой таблице вместо того, чтобы обновлять множество записей в основной базе. Аналогичные рассуждения применимы и к таблице authors, связанной с books по полю authorjd.

Тщательное планирование также помогает избежать ошибок при выборе типов данных. Например, таблица editions связывает коды ISBN с кодами книг, хранящимися в таблице booktown. На первый взгляд кажется, что для представления кодов ISBN можно воспользоваться полем типа integer, однако такое решение было бы ошибочным, поскольку коды ISBN иногда содержат символьные данные. Кроме того, в поле типа integer будут теряться начальные нули (код 0451160916 превратится в 451160916).

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