Bir önceki yazımda PostgreSQL’de schema kavramından ve obje hiyerarşi’sinden bahsetmiştim. Bu yazımızda schema kavramını detaylandıracağız. Önceki yazıdada bahsettiğim gibi PostgreSQL veritabanı cluster, bir veya daha fazla veritabanı içerebilir. Roller ve diğer birkaç nesne türü, tüm cluster genelinde paylaşılır yani global nesnelerdir. Sunucuya ise client bağlantısı, yalnızca bağlantı isteğinde, belirtilen tek bir veritabanındaki verilere erişebilir.

Veritabanı ise tabloları ve objeleri içeren bir veya daha fazla schema’ya sahip olabilir, yani her schema yalnızca bir veri tabanına ait olabilirken  bir veri tabanında birden çok schema yaratılabilir. Farklı isimdeki iki schema, aynı isimde objeler içerebilir. Aslında burada schema kavramı veritabanı objeleri için namespace anlamına gelmektedir. Veri tabanı objesine erişmek istendiği zaman schema_name.object_name isimlendirmesi kullanılır. Veritabanlarından farklı olarak, schemalar katı bir şekilde ayrılmaz: bir kullanıcı, yetkileri varsa, bağlı oldukları veritabanındaki schemaların herhangi birindeki objelere erişebilir.  Schemaları kullanmak istemenin birkaç nedeni vardır;

  • Birçok kullanıcının birbirine müdahale etmeden, veritabanını kullanmasına izin vermek için.
  • Veritabanı objelerini daha yönetilebilir hale getirmek için mantıksal gruplar halinde düzenlemek.
  • Üçüncü taraf uygulamalar, diğer objelerin adlarıyla çakışmaması için ayrı schemalara yerleştirilebilir.
  • Schemalar, işletim sistemi düzeyindeki dizinlere benzer, ancak schemalar iç içe olamaz.

Bir schema oluşturmak için CREATE SCHEMA komutu kullanılır.

CREATE SCHEMA schema_name;

Başkasına ait bir schema oluşturmak istersek aşağıdaki gibi oluşturmamız gerek.

CREATE SCHEMA schema_name AUTHORIZATION user_name;

Bir schemada nesneler oluşturmak veya bunlara erişmek için, schema adı ve nokta ile ayrılmış tablo adından oluşan komut yazılır.

create table schema_name.table_name(id int);
create table database_name.schema_name.table_name(id int);

Bir schema boş ve silmek istiyorsak aşağıdaki komutu kullanabiliriz.

DROP SCHEMA schema_name;

İçindeki objelerle beraber schemayı silmek istersek aşağıdaki komutu kullanabiliriz.

DROP SCHEMA schema_name CASCADE;

Varolan schemaları aşağıdaki komutlarla öğrenebiliriz \dn (default namespace) komutu ile yada pg_namespace sistem viewini sorgulayarak öğrenebiliriz;

\dn
postgres=# select * from pg_namespace ;
  oid  |      nspname       | nspowner |               nspacl                
-------+--------------------+----------+-------------------------------------
    99 | pg_toast           |       10 | 
 12314 | pg_temp_1          |       10 | 
 12315 | pg_toast_temp_1    |       10 | 
    11 | pg_catalog         |       10 | {postgres=UC/postgres,=U/postgres}
  2200 | public             |       10 | {postgres=UC/postgres,=UC/postgres}
 13887 | information_schema |       10 | {postgres=UC/postgres,=U/postgres}
(6 rows)
 

Postgresql’de yeni oluşturulan her veri tabanında public isimli bir schema bulunur. Veri tabanında schema adı belirtmeden bir obje yaratıldığı zaman otomatik olarak objeler public schemasında yaratılır. Yani Public schema veri tabanları için default schemadır.

Bir schema oluşturmak için CREATE SCHEMA komutu kullanılır.

CREATE TABLE table_name (id int);
CREATE TABLE public.table_name (id int);

Tablolara genellikle yalnızca tablo adından oluşan komutlarla çağrılır. Sistem, aranacak schemaların bir listesi olan arama yolunu(search path) izleyerek hangi tablonun kastedildiğini belirler. Arama yolundaki ilk eşleşen tablo, aranan tablo olarak alınır. Arama yolunda(search path) eşleşme yoksa, veritabanındaki diğer schemalarda eşleşen tablo adları bulunsa bile bir hata bildirilir. Arama yolunda adı geçen ilk schemaya “current schema” denir. Mevcut arama yolunu göstermek için aşağıdaki komutu kullanırız;

 postgres=# SHOW search_path;
   search_path   
-----------------
 "$user", public
(1 row)

postgres=# 
postgres=# SELECT current_schema();
 current_schema 
----------------
 public
(1 row)

“Search_path” sorgusu sonucu gelen “$user” çıktısı , mevcut kullanıcı ile aynı ada sahip bir schemanın aranacağını belirtir. Böyle bir schema yoksa, giriş dikkate alınmaz. İkinci öğe, daha önce gördüğümüz public schemaya atıfta bulunur. İkinci sorgu(current_schame) ile’demevcut kullanıcımızı görebiliriz.

Search path’deki ilk schema, yeni nesneler oluşturmak için varsayılan konumdur. Varsayılan olarak public schemada objelerin yaratılmasının nedeni budur. Yani veri tabanı objesi schema adı verilmeden oluşturulmaya çalışıldığında Search path’e hangi schema adı ilk önce yazılır ise o schemada yaratılır.

postgres=# create schema testschema;
CREATE SCHEMA
postgres=# SHOW search_path;
   search_path   
-----------------
 "$user", public
(1 row)

postgres=# SET search_path TO 'test_schema','$user','public';
SET
postgres=# SHOW search_path;
         search_path          
------------------------------
 test_schema, "$user", public
(1 row)

postgres=# create table test_table(id int);
CREATE TABLE
postgres=# \dt
              List of relations
   Schema    |    Name    | Type  |  Owner   
-------------+------------+-------+----------
 test_schema | test_table | table | postgres
(1 row) 

Varsayılan olarak, kullanıcılar sahip olmadıkları schemalardaki herhangi bir nesneye erişemezler. Buna izin vermek için, schema sahibinin şema üzerinde “USAGE” yetkisini vermesi gerekir. Kullanıcıların schemadaki nesneleri kullanmalarına izin vermek için, nesneye uygun olarak ek yetkilerin verilmesi gerekebilir.

Bir kullanıcının başka birinin schemasında nesneler oluşturmasına da izin verilebilir. Buna izin vermek için, şemada CREATE yetkisinin verilmesi gerekir. Varsayılan olarak, herkesin public schema üzerinde CREATE ve USAGE yetkilerine sahip olduğunu bilmemiz gerekir. Burada tavsiye olarak public schemasını kullanmamınızı öneririm, bunun yerine her projeye özgü schema yaratıp kullanmanın daha iyi olduğunu düşünüyorum, hatta bunu biraz zorlamak içinde search_path’deki public verisini silmenin yararlı olacağını düşünüyorum. Public schemasındaki yetkileri almak istersek aşağıdaki komutu çalıştırabiliriz;

REVOKE CREATE ON SCHEMA public FROM PUBLIC; 

NOT : Burada ilk public kelimesi schemayı temsil eder, ikinci PUBLIC kelimesi ise bütün kullanıcıları temsil eder.

Public ve kullanıcı tarafından oluşturulan schemalara ek olarak, her veritabanı sistem tablolarını ve tüm built-in veri türlerini, fonksiyonları ve operatörlerini içeren bir pg_catalog scheması içerir. pg_catalog her zaman etkin bir şekilde search_path’in bir parçasıdır. Path’de açık bir şekilde adlandırılmamışsa, path’in schemalarının aramadan önce dolaylı olarak aranır. Bu, built-in adların her zaman bulunabilir olmasını sağlar.

Mustafa Bektaş Tepe
İyi Çalışmalar

Loading