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の順。



以上 
inserted by FC2 system