10.4. Хранимое значение
Значения, вставляемые в таблицу, преобразуется в тип данных целевого столбца по следующему алгоритму.
Преобразование по типу хранения
Проверить точное совпадение с целевым типом.
Если типы не совпадают, попытаться привести тип к целевому. Это возможно, если в каталоге
pg_cast
(см. CREATE CAST) зарегистрировано приведение присваивания между двумя типами. Если же результат выражения — строка неизвестного типа, содержимое этой строки будет подано на вход процедуре ввода целевого типа.Проверить, не требуется ли приведение размера для целевого типа. Приведение размера — это преобразование типа к такому же. Если это приведение описано в каталоге
pg_cast
, применить к его к результату выражения, прежде чем сохранить в целевом столбце. Функция, реализующая такое приведение, всегда принимает дополнительный параметр типаinteger
, в котором передаётся значениеatttypmod
для целевого столбца (обычно это её объявленный размер, хотя интерпретироваться значениеatttypmod
для разных типов данных может по-разному), и третий параметр типаboolean
, передающий признак явное/неявное преобразование. Функция приведения отвечает за все операции с длиной, включая её проверку и усечение данных.
Пример 10.9. Преобразование для типа хранения character
Следующие запросы показывают, что сохраняемое значение подгоняется под размер целевого столбца, объявленного как character(20)
:
CREATE TABLE vv (v character(20)); INSERT INTO vv SELECT 'abc' || 'def'; SELECT v, octet_length(v) FROM vv; v | octet_length ----------------------+-------------- abcdef | 20 (1 row)
Суть происходящего здесь в том, что две константы неизвестного типа по умолчанию воспринимаются как значения text
, что позволяет применить к ним оператор ||
как оператор конкатенации значений text
. Затем результат оператора, имеющий тип text
, приводится к типу bpchar
(«blank-padded char» (символы, дополненные пробелами), внутреннее имя типа character
) в соответствии с типом целевого столбца. (Так как типы text
и bpchar
двоично-совместимы, при этом преобразовании реальный вызов функции не добавляется.) Наконец, в системном каталоге находится функция изменения размера bpchar(bpchar, integer, boolean)
и применяется для результата оператора и длины столбца. Эта связанная с типом функция проверяет длину данных и добавляет недостающие пробелы.
3.3. Foreign Keys
Recall the weather
and cities
tables from Chapter 2. Consider the following problem: You want to make sure that no one can insert rows in the weather
table that do not have a matching entry in the cities
table. This is called maintaining the referential integrity of your data. In simplistic database systems this would be implemented (if at all) by first looking at the cities
table to check if a matching record exists, and then inserting or rejecting the new weather
records. This approach has a number of problems and is very inconvenient, so Postgres Pro can do this for you.
The new declaration of the tables would look like this:
CREATE TABLE cities ( name varchar(80) primary key, location point ); CREATE TABLE weather ( city varchar(80) references cities(name), temp_lo int, temp_hi int, prcp real, date date );
Now try inserting an invalid record:
INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');
ERROR: insert or update on table "weather" violates foreign key constraint "weather_city_fkey" DETAIL: Key (city)=(Berkeley) is not present in table "cities".
The behavior of foreign keys can be finely tuned to your application. We will not go beyond this simple example in this tutorial, but just refer you to Chapter 5 for more information. Making correct use of foreign keys will definitely improve the quality of your database applications, so you are strongly encouraged to learn about them.