PostgreSQL表空間、模式、表、用戶/角色之間的關(guān)系
PostgreSQL表空間、模式、表、用戶/角色之間的關(guān)系是本文我們主要要介紹的內(nèi)容,表空間,數(shù)據(jù)庫,模式,表,用戶,角色之間的關(guān)系到底是怎樣的呢?接下來我們就開始介紹這一過程。
實驗出角色與用戶的關(guān)系
在PostgreSQL中,存在兩個容易混淆的概念:角色/用戶。之所以說這兩個概念容易混淆,是因為對于PostgreSQL來說,這是完全相同的兩個對象。唯一的區(qū)別是在創(chuàng)建的時候:
1.我用下面的psql創(chuàng)建了角色kanon:CREATE ROLE kanon PASSWORD 'kanon';接著我使用新創(chuàng)建的角色kanon登錄,PostgreSQL給出拒絕信息:FATAL: role 'kanon' is not permitted to log in.說明該角色沒有登錄權(quán)限,系統(tǒng)拒絕其登錄。
2.我又使用下面的psql創(chuàng)建了用戶kanon2:CREATE USER kanon PASSWORD 'kanon2';接著我使用kanon2登錄,登錄成功。難道這兩者有區(qū)別嗎?查看文檔,又這么一段說明:"CREATE USER is the same as CREATE ROLE except that it implies LOGIN."----CREATE USER除了默認(rèn)具有LOGIN權(quán)限之外,其他與CREATE ROLE是完全相同的。
為了驗證這句話,修改kanon的權(quán)限,增加LOGIN權(quán)限:ALTER ROLE kanon LOGIN;再次用kanon登錄,成功!那么,事情就明了了:CREATE ROLE kanon PASSWORD 'kanon' LOGIN 等同于CREATE USER kanon PASSWORD 'kanon'.這就是ROLE/USER的區(qū)別。
數(shù)據(jù)庫與模式的關(guān)系
模式(schema)是對數(shù)據(jù)庫(database)邏輯分割。
在數(shù)據(jù)庫創(chuàng)建的同時,就已經(jīng)默認(rèn)為數(shù)據(jù)庫創(chuàng)建了一個模式--public,這也是該數(shù)據(jù)庫的默認(rèn)模式。所有為此數(shù)據(jù)庫創(chuàng)建的對象(表、函數(shù)、試圖、索引、序列等)都是常見在這個模式中的。
實驗如下:
1.創(chuàng)建一個數(shù)據(jù)庫dbtt----CREATE DATABASE dbtt;
2.用kanon角色登錄到dbtt數(shù)據(jù)庫,查看dbtt數(shù)據(jù)庫中的所有模式:/dn; 顯示結(jié)果是只有public一個模式。
3.創(chuàng)建一張測試表----CREATE TABLE test(id integer not null);
4.查看當(dāng)前數(shù)據(jù)庫的列表: /d; 顯示結(jié)果是表test屬于模式public.也就是test表被默認(rèn)創(chuàng)建在了public模式中。
5.創(chuàng)建一個新模式kanon,對應(yīng)于登錄用戶kanon:CREATE SCHEMA kanon OWNER kanon;
6.再次創(chuàng)建一張test表,這次這張表要指明模式----CREATE TABLE kanon.test (id integer not null);
7.查看當(dāng)前數(shù)據(jù)庫的列表: /d; 顯示結(jié)果是表test屬于模式kanon.也就是這個test表被創(chuàng)建在了kanon模式中。得出結(jié)論是:數(shù)據(jù)庫是被模式(schema)來切分的,一個數(shù)據(jù)庫至少有一個模式,所有數(shù)據(jù)庫內(nèi)部的對象(object)是被創(chuàng)建于模式的。用戶登錄到系統(tǒng),連接到一個數(shù)據(jù)庫后,是通過該數(shù)據(jù)庫的search_path來尋找schema的搜索順序,可以通過命令SHOW search_path;具體的順序,也可以通過SET search_path TO 'schema_name'來修改順序。
官方建議是這樣的:在管理員創(chuàng)建一個具體數(shù)據(jù)庫后,應(yīng)該為所有可以連接到該數(shù)據(jù)庫的用戶分別創(chuàng)建一個與用戶名相同的模式,然后,將search_path設(shè)置為"$user",
這樣,任何當(dāng)某個用戶連接上來后,會默認(rèn)將查找或者定義的對象都定位到與之同名的模式中。這是一個好的設(shè)計架構(gòu)。
表空間與數(shù)據(jù)庫的關(guān)系
數(shù)據(jù)庫創(chuàng)建語句CREATE DATABASE dbname 默認(rèn)的數(shù)據(jù)庫所有者是當(dāng)前創(chuàng)建數(shù)據(jù)庫的角色,默認(rèn)的表空間是系統(tǒng)的默認(rèn)表空間--pg_default。
為什么是這樣的呢?因為在PostgreSQL中,數(shù)據(jù)的創(chuàng)建是通過克隆數(shù)據(jù)庫模板來實現(xiàn)的,這與SQL SERVER是同樣的機(jī)制。
由于CREATE DATABASE dbname并沒有指明數(shù)據(jù)庫模板,所以系統(tǒng)將默認(rèn)克隆template1數(shù)據(jù)庫,得到新的數(shù)據(jù)庫dbname。(By default, the new database will be created by cloning the standard system database template1).
而template1數(shù)據(jù)庫的默認(rèn)表空間是pg_default,這個表空間是在數(shù)據(jù)庫初始化時創(chuàng)建的,所以所有template1中的對象將被同步克隆到新的數(shù)據(jù)庫中。
相對完整的語法應(yīng)該是這樣的:CREATE DATABASE dbname OWNER kanon TEMPLATE template1 TABLESPACE tablespacename;
下面我們來做個實驗驗證一下:
1.連接到template1數(shù)據(jù)庫,創(chuàng)建一個表作為標(biāo)記:CREATE TABLE tbl_flag(id integer not null);向表中插入數(shù)據(jù)INSERT INTO tbl_flag VALUES (1);
2.創(chuàng)建一個表空間:CREATE TABLESPACE tskanon OWNER kanon LOCATION '/tmp/data/tskanon';在此之前應(yīng)該確保目錄/tmp/data/tskanon存在,并且目錄為空。
3.創(chuàng)建一個數(shù)據(jù)庫,指明該數(shù)據(jù)庫的表空間是剛剛創(chuàng)建的tskanon:CREATE DATABASE dbkanon TEMPLATE template1 OWNERE kanon TABLESPACE tskanon;
4.查看系統(tǒng)中所有數(shù)據(jù)庫的信息:/l;可以發(fā)現(xiàn),dbkanon數(shù)據(jù)庫的表空間是tskanon,擁有者是kanon;
5.連接到dbkanon數(shù)據(jù)庫,查看所有表結(jié)構(gòu):/d;可以發(fā)現(xiàn),在剛創(chuàng)建的數(shù)據(jù)庫中居然有了一個表tbl_flag,查看該表數(shù)據(jù),輸出結(jié)果一行一列,其值為1,說明,該數(shù)據(jù)庫的確是從template1克隆而來。
仔細(xì)分析后,不難得出結(jié)論:在PostgreSQL中,表空間是一個目錄,里面存儲的是它所包含的數(shù)據(jù)庫的各種物理文件。
總結(jié):
表空間是一個存儲區(qū)域,在一個表空間中可以存儲多個數(shù)據(jù)庫,盡管PostgreSQL不建議這么做,但我們這么做完全可行。一個數(shù)據(jù)庫并不知直接存儲表結(jié)構(gòu)等對象的,而是在數(shù)據(jù)庫中邏輯創(chuàng)建了至少一個模式,在模式中創(chuàng)建了表等對象,將不同的模式指派該不同的角色,可以實現(xiàn)權(quán)限分離,又可以通過授權(quán),實現(xiàn)模式間對象的共享,并且,還有一個特點就是:public模式可以存儲大家都需要訪問的對象。
這樣,我們的網(wǎng)就形成了。可是,既然一個表在創(chuàng)建的時候可以指定表空間,那么,是否可以給一個表指定它所在的數(shù)據(jù)庫表空間之外的表空間呢?答案是肯定的!這么做完全可以:那這不是違背了表屬于模式,而模式屬于數(shù)據(jù)庫,數(shù)據(jù)庫最終存在于指定表空間這個網(wǎng)的模型了嗎?!是的,看上去這確實是不合常理的,但這么做又是有它的道理的,而且現(xiàn)實中,我們往往需要這么做:將表的數(shù)據(jù)存在一個較慢的磁盤上的表空間,而將表的索引存在于一個快速的磁盤上的表空間。
但我們再查看表所屬的模式還是沒變的,它依然屬于指定的模式。所以這并不違反常理。實際上,PostgreSQL并沒有限制一張表必須屬于某個特定的表空間,我們之所以會這么認(rèn)為,是因為在關(guān)系遞進(jìn)時,偷換了一個概念:模式是邏輯存在的,它不受表空間的限制。
關(guān)于PostgreSQL表空間、模式、表、用戶/角色之間的關(guān)系的相關(guān)知識就介紹到這里了,希望本次的介紹能夠?qū)δ兴斋@!
【編輯推薦】


2009-11-04 11:03:08
2009-11-24 17:20:48
2016-12-27 15:47:19




