postgresql 중schema 개념

schema 개념은 약간 명칭 공간이나 그것을 하나의 파일 시스템의 디렉터리로 상상하는 것과 같다. 차이점은 이 schema 아래에 schema가 더 이상 끼워 넣을 수 없다는 것이다.각 대상, 예를 들어 표, 함수 등은 각schema 아래에 저장되고 같은 schema 아래에 중복된 대상의 이름은 있을 수 없지만 서로 다른 schema 아래에서 중복될 수 있다.
schema 역할 사용하기
  • 여러 사용자가 하나의 데이터베이스를 공유하는 것을 관리하기 편리하지만 서로 독립할 수 있다.
  • 여러 객체를 간편하게 관리하고 논리적으로 관리할 수 있음
  • 일부 제3자 응용 프로그램을 호환하기 편리하고 대상을 만들 때 schema가 있다
  • 예를 들어 복잡한 시스템을 설계해야 한다.많은 모듈로 구성되어 있으며, 때로는 모듈 간에 독립성이 필요하다.각 모듈에 단독 데이터베이스를 저장하는 것은 분명히 적합하지 않다.이때 schema를 사용하여 각 모듈 간의 대상을 분류하고 사용자에게 적당한 권한 제어를 한다.이렇게 논리도 매우 뚜렷하다.

    schema 만들기

    db01=# create schema schema01;
    CREATE SCHEMA
    db01=# \dn
       List of schemas
       Name   |  Owner   
    ----------+----------
     public   | postgres
     schema01 | postgres
    (2 rows)
    

    schema에서 객체 만들기

    db01=# create table schema01.t1(id int);
    CREATE TABLE
    db01=# insert into schema01.t1 values(1);
    INSERT 0 1
    db01=# select * from t1;
    ERROR:  relation "t1" does not exist
    LINE 1: select * from t1;
                          ^
    db01=# select * from schema01.t1;
     id 
    ----
      1
    (1 row)
    db01=# select * from db01.schema01.t1;
     id 
    ----
      1
    (1 row)
    

    기본값은 공공 이 schema 아래에 있습니다.그래서 schema 이름을 붙여야 합니다.데이터베이스 이름을 가져오려면 현재 연결된 데이터베이스만 가능합니다!!

    삭제

    db01=# drop schema schema01;
    ERROR:  cannot drop schema schema01 because other objects depend on it
    DETAIL:  table schema01.t1 depends on schema schema01
    HINT:  Use DROP ... CASCADE to drop the dependent objects too.
    db01=# drop schema schema01 cascade;
    NOTICE:  drop cascades to table schema01.t1
    DROP SCHEMA
    

    schema 아래에 대상이 있습니다. 같이 삭제할 필요가 있으면cascade 키워드를 가져가야 합니다.rmdir로 디렉터리를 삭제하는 것처럼 폴더 밑에 물건이 있으면 삭제하지 않습니다.

    schema 지정 owner 만들기


    기본적으로 누가 만든 schema,owner가 누구인지 지정할 수 있습니다
    db01=# create schema s01 authorization hippo;
    CREATE SCHEMA
    db01=# create schema authorization hippo;
    CREATE SCHEMA
    db01=# \dn
      List of schemas
      Name  |  Owner   
    --------+----------
     hippo  | hippo
     public | postgres
     s01    | hippo
    (3 rows)
    

    owner를 지정하고 schema를 지정하지 않으면 schema 이름이 owner와 일치합니다
    oracle에서 기본적으로 사용자를 만들 때 사용자 이름과 같은 schema를 만들고 서로 연결합니다.여기 약간 비슷해요.

    검색 경로(Search Path)


    만약 모든 schema 아래에 같은 이름의 대상(예를 들어 표t)이 있다면, 내가 조회한 것은 어느 schema 아래의 표일까요?
    pg에서 검색 경로 매개 변수를 통해 제어,searchpath, 우리 먼저 데이터를 시뮬레이션합시다
    db01=# \c - hippo
    You are now connected to database "db01" as user "hippo".
    db01=# create table public.t1(id text);
    CREATE TABLE
    db01=# insert into public.t1 values('public');
    INSERT 0 1
    db01=# create table s01.t1(id text);
    CREATE TABLE
    db01=# insert into s01.t1 values('s01');
    INSERT 0 1
    db01=# create table hippo.t1(id text);
    CREATE TABLE
    db01=# insert into hippo.t1 values('hippo');
    INSERT 0 1
    db01=> select * from pg_tables where tablename = 't1';
     schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastriggers 
    ------------+-----------+------------+------------+------------+----------+-------------
     public     | t1        | hippo      |            | f          | f        | f
     s01        | t1        | hippo      |            | f          | f        | f
     hippo      | t1        | hippo      |            | f          | f        | f
    (3 rows)
    

    테스트
    db01=> show search_path;
      search_path   
    ----------------
     "$user",public
    (1 row)
    
    db01=> select * from t1;
      id   
    -------
     hippo
    (1 row)
    
    db01=> set search_path = 's01';
    SET
    db01=> select * from t1;
     id  
    -----
     s01
    (1 row)
    

    검색 경로에 없으면 다른 schema가 있어도 찾을 수 없습니다.
    db01=> drop table t1;
    DROP TABLE
    db01=> select * from t1;
    ERROR:  relation "t1" does not exist
    LINE 1: select * from t1;
                          ^
    

    생성된 테이블에 어떤 schema를 저장할 것인지도 검색path 관련
    db01=> set search_path=ssssss,s01;
    SET
    db01=> create table t2(id int);
    CREATE TABLE
    db01=> \dt        --ssssss schema 
           List of relations
     Schema | Name | Type  | Owner 
    --------+------+-------+-------
     s01    | t2   | table | hippo
    (1 row)
    
    db01=> set search_path='';
    SET
    db01=> create table t3(id int);
    ERROR:  no schema has been selected to create in
    

    어떤 사용자인지와는 상관없이 왜 이전에 만든 시계가 왜 모두 공공장소에서 만들어졌는지 이제 알겠죠

    schema와 권한


    login 권한이 있는 사용자만 owner가 자신의 schema가 아닌 경우 어떠한 권한도 없습니다
    db01=> \c - postgres
    db01=# create schema s02;
    CREATE SCHEMA
    db01=# create role u02 login;
    CREATE ROLE
    db01=# create table s02.t1(id int);
    CREATE TABLE
    db01=# \c - u02
    You are now connected to database "db01" as user "u02".
    db01=> select * from s02.t1;
    ERROR:  permission denied for schema s02
    LINE 1: select * from s02.t1;
                          ^
    db01=> create table s02.t2(id int);
    ERROR:  permission denied for schema s02
    

    usage 권한 부여
    db01=> \c - postgres
    You are now connected to database "db01" as user "postgres".
    db01=# grant usage on schema s02 to u02;
    GRANT
    db01=# \c - u02;
    You are now connected to database "db01" as user "u02".
    db01=> select * from s02.t1;
    ERROR:  permission denied for relation t1
    

    주의해라, 여기 제시된 오류는 이미 다르다.에 대한 질의 권한이 없습니다.
    db01=# grant select on all tables in schema s02 to u02;
    GRANT
    db01=# \c - u02
    You are now connected to database "db01" as user "u02".
    db01=> select * from s02.t1;
     id 
    ----
    (0 rows)
    

    시스템은 기본적으로 usage,create 권한을 PUBLIC(모든 사용자)에게 부여하기 때문에 이전에 새로 만든 사용자가 표를 만들 수 있는 이유가 바로 이 때문입니다.
    db01=> create table public.t2(id int);
    CREATE TABLE
    db01=# revoke usage,create on schema public from public;
    REVOKE
    db01=# \c - u02
    You are now connected to database "db01" as user "u02".
    db01=> \dt
    No relations found.
    db01=> select * fromt t2;
    ERROR:  syntax error at or near "fromt"
    LINE 1: select * fromt t2;
                     ^
    

    시스템 schema, pgcatalog


    pg_catalog는 각 시스템 테이블, 내장 함수 등을 저장합니다. 검색 경로에서current 를 통과해야 합니다.schemas 보이다
    db01=> \c - hippo
    You are now connected to database "db01" as user "hippo".
    db01=> show search_path;
      search_path   
    ----------------
     "$user",public
    (1 row)
    
    db01=> select current_schemas(true);
          current_schemas      
    ---------------------------
     {pg_catalog,hippo,public}
    (1 row)
    
    db01=> set search_path='';
    SET
    db01=> select current_schemas(true);
     current_schemas 
    -----------------
     {pg_catalog}
    (1 row)
    

    schema 사용 예

    db02=> \c - postgres
    You are now connected to database "db02" as user "postgres".
    db02=# drop schema public;
    DROP SCHEMA
    db02=# create role jack login;
    CREATE ROLE
    db02=# create role joe login;
    CREATE ROLE
    db02=# create schema authorization jack;
    CREATE SCHEMA
    db02=# create schema authorization joe;
    CREATE SCHEMA
    db02=# grant usage on schema jack to joe;
    GRANT
    db02=# grant usage on schema joe;
    GRANT
    db02=# grant select on all tables in schema jack to joe;
    GRANT
    db02=# grant select on all tables in schema joe to jack;
    GRANT
    

    public 이 schema를 삭제하면 사용자가 자신의 schema에서만 활동할 수 있도록 제한합니다. public에서 너무 많은 공간을 차지하는 것을 방지하면 제한 권한이 있는 사용자를 만들 수 있습니다. 예를 들어 삭제, 수정 권한이 있는 사용자만 특정한 schema에 접근할 수 있습니다. 이를 수정하는 검색path grant select on all tables in schema .. to .. 문장은 현재 schema의 표에만 영향을 주고, 이후에 만든 표는 영향을 받지 않습니다. 이것은 주의해야 합니다.
    //END

    좋은 웹페이지 즐겨찾기