PostgreSQLスキルアップノート(自己啓発のための個人サイト)
スキーマ検索パス
【一覧に戻る】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■■■■ PostgreSQL スキルアップノート
■■■■
■◆■■ スキーマ検索パス
■■■■
■■■■
■■■■ 2013/02/05
■■■■ 使用環境:PostgreSQL9.1.7 (CentOS6.2)
(C) 2013 ohdb
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
★自己都合により実機確認は9.1、マニュアルへのリンクは9.2としています。ご了承下さい。
【マニュアル】
スキーマ→●[マニュアル]
CREATE SCHEMA→●[マニュアル]
テーブル名が同じでスキーマ名が異なる3つのテーブルを使用してどのテーブルがアクセスされるのかの確認。
(スキーマ検索パス)
■1■ 現在のスキーマの確認
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
このページでは前ページで作成したスキーマが必要。
【□】 psql database1 user01
【□】 \dn+
スキーマ一覧
名前 | 所有者 | アクセス権 | 説明
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres+| standard public schema
| | =UC/postgres |
scm01 | dba01 | dba01=UC/dba01 +|
| | user01=UC/dba01 |
user01 | user01 | |
user01がアクセスできるのは
・publicスキーマ
・権限の与えられたscm01スキーマ
・user01が所有者となっているuser01スキーマ
の3つのスキーマである。
■2■ 検証用テーブル作成
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
前ページで作成したスキーマを使用して同名の3つのテーブルを作成。
【□】 psql database1 user01
【□】テーブルの作成
DROP TABLE public.t1,scm01.t1,user01.t1;
CREATE TABLE public.t1(c1 TEXT);INSERT INTO public.t1 VALUES('t1 in public');
CREATE TABLE scm01.t1 (c1 TEXT);INSERT INTO scm01.t1 VALUES('t1 in scm01');
CREATE TABLE user01.t1(c1 TEXT);INSERT INTO user01.t1 VALUES('t1 in user01');
■3■ 同名テーブルの確認(3個のt1テーブル)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
作成した3個のt1テーブルを確認してみる。
【□】 \dt *.t1
リレーションの一覧
スキーマ | 名前 | 型 | 所有者
----------+------+----------+--------
public | t1 | テーブル | user01
scm01 | t1 | テーブル | user01
user01 | t1 | テーブル | user01
以上より、ユーザuser01は
・publicスキーマに作成したt1
・自分に権限が与えられているscm01スキーマにあるt1
・自分が所有者のuser01スキーマにあるt1
の3つの同名のテーブルを持ってしまっている。
■4■ SELECTによりアクセス
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
user01でログインし、スキーマ名を明示せずにselectしたらどこへアクセスするか?
【□】 psql database1 user01
【□】 select * from t1;
c1
--------------
t1 in user01
■5■ スキーマの検索順位「検索パス」
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
user01スキーマのt1へアクセスしたのは「スキーマ検索パス」による。
スキーマ検索パス→●[マニュアル]
■6■ スキーマ検索パスの確認
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
現在の(デフォルトの)スキーマ検索パスがどうなっているのかを以下により確認
【□】 show search_path;
search_path
----------------
"$user",public
以上より、デフォルトでは
・user名と同じ名前のスキーマが最優先。("$user")※
・publicはその次
・scm01スキーマは検索パスには設定されていない。
したがって、user名と同じuser01スキーマの中にあるt1テーブルが検索の対象になった。
もし、user01.t1が存在しなければ、次の優先であるpublicにあるt1テーブルがアクセス対象になる。
※最優先である一番左に設定されたスキーマを「現在のスキーマ」と呼ぶ
本当は「カレントスキーマ」のはずが訳されてしまっている?
■7■ テーブルの存在を変えて確認
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
スキーマ検索パスによるアクセスを確認。
search_pathはデフォルトの "$user",publicとなっている状態で実施。
【□】 psql database1 user01
【□】 \dt *.t1
リレーションの一覧
スキーマ | 名前 | 型 | 所有者
----------+------+----------+--------
public | t1 | テーブル | user01
scm01 | t1 | テーブル | user01
user01 | t1 | テーブル | user01
【□】 select * from t1;
c1
--------------
t1 in user01
【□】 drop table user01.t1;
【□】 \dt *.t1
リレーションの一覧
スキーマ | 名前 | 型 | 所有者
----------+------+----------+--------
public | t1 | テーブル | user01
scm01 | t1 | テーブル | user01
【□】 select * from t1;
c1
--------------
t1 in public
【□】 drop table public.t1;
【□】 \dt *.t1
リレーションの一覧
スキーマ | 名前 | 型 | 所有者
----------+------+----------+--------
scm01 | t1 | テーブル | user01
【□】 select * from t1;
ERROR: relation "t1" does not exist
行 1: select * from t1;
・・・スキーマ検索パスにscm01がないため、scm01へはスキーマ名を明示しないアクセスは不可。
■7■ スキーマ検索パスの設定、変更について
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
スキーマ検索パスは以下によりセッションの中で設定することができる。
【□】 SET search_path TO scm01,public;
【□】 select * from t1;
c1
-------------
t1 in scm01
スキーマ検索パスのデフォルトの設定はpostgresql.confで行うことができる。
【□】 cat $PGDATA/postgresql.conf
#search_path = '"$user",public' # schema names
デフォルトのpostgresql.confでは上記のようなコメントとなっている。
したがってデフォルトでは"$user",publicの順。
以上