Таблицы в 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).
Из всего сказанного можно сделать вывод, что проектирование таблиц является важной составляющей процесса проектирования базы данных.
Назад | Содержание |