PostgreSQL【表】

1、表的定義:

    對於任何一種關係型數據庫而言,表都是數據存儲的最核心、最基礎的對象單元。如今就讓咱們從這裏起步吧。
     1. 建立表:
    CREATE TABLE products (
        product_no integer,
        name text,
        price numeric
    );
    
     2. 刪除表:
     DROP TABLE products;
    
     3. 建立帶有缺省值(默認值)的表:
    CREATE TABLE products (
        product_no integer,
        name text,
        price numeric DEFAULT 9.99 --DEFAULT是關鍵字,其後的數值9.99是字段price的默認值。
    );
    
    CREATE TABLE products (
        product_no SERIAL,            --SERIAL類型的字段表示該字段爲自增字段,徹底等同於Oracle中的Sequence
        name text,
        price numeric DEFAULT 9.99
    );
    輸出爲:
     NOTICE:  CREATE TABLE will create implicit sequence "products_product_no_seq" for serial column "products.product_no"
   
     4. 約束:
    【檢查約束】是表中最爲常見的約束類型,它容許你聲明在某個字段裏的數值必須知足一個布爾表達式。不只如此,咱們也能夠聲明表級別的檢查約束。
    CREATE TABLE products (
        product_no integer,
        name text,
        --price字段的值必須大於0,不然在插入或修改該字段值是,將引起違規錯誤。還須要說明的是,該檢查約束
        --是匿名約束,即在表定義時沒有顯示命名該約束,這樣PostgreSQL將會根據當前的表名、字段名和約束類型,
        --爲該約束自動命名,如:products_price_check。
        price numeric CHECK (price > 0)
    );
 
    CREATE TABLE products (
        product_no integer,
        name text,
        --該字段的檢查約束被顯示命名爲positive_price。這樣作好處在於從此維護該約束時,能夠根據該名進行直接操做。
        price numeric CONSTRAINT positive_price CHECK (price > 0)
    );
    【非空約束】即約束的字段不能插入空值,或者是將已有數據更新爲空值。
    CREATE TABLE products (
        product_no integer NOT NULL,
        name text NOT NULL,
        price numeric
    );
    若是一個字段中存在多個約束,在定義時能夠不用考慮約束的聲明順序。
    CREATE TABLE products (
        product_no integer NOT NULL,
        name text NOT NULL,
        price numeric NOT NULL CHECK (price > 0)
    );
    【惟一性約束】,即指定的字段不能插入重複值,或者是將某一記錄的值更新爲當前表中的已有值。
    CREATE TABLE products (
        product_no integer UNIQUE,
        name text,
        price numeric
    );

    CREATE TABLE products (
        product_no integer,
        name text,
        price numeric,
        UNIQUE (product_no)
    );
    爲表中的多個字段定義【聯合惟一性】。
    CREATE TABLE example (
        a integer,
        b integer,
        c integer,
        UNIQUE (a, c)
    );
    爲惟一性約束命名。
    CREATE TABLE products (
        product_no integer CONSTRAINT must_be_different UNIQUE,
        name text,
        price numeric
    );
    在插入數據時,空值(NULL)之間被視爲不相等的數據,所以對於某一惟一性字段,能夠屢次插入空值。然而須要注意的是,這一規則並非被全部數據庫都遵照,所以在進行數據庫移植時可能會形成必定的麻煩。
   
     5. 主鍵和外鍵:
    從技術上來說,【主鍵約束】只是惟一約束和非空約束的組合。
    CREATE TABLE products (
        product_no integer PRIMARY KEY--字段product_no被定義爲該表的惟一主鍵。
        name text,
        price numeric
    );
    和惟一性約束同樣,主鍵能夠同時做用於多個字段,造成聯合主鍵:
    CREATE TABLE example (
        a integer,
        b integer,
        c integer,
        PRIMARY KEY (b, c)
    );
    【外鍵約束】聲明一個字段(或者一組字段)的數值必須匹配另一個表中某些行出現的數值。 咱們把這個行爲稱作兩個相關表之間的參考完整性。
    CREATE TABLE orders (
        order_id integer PRIMARY KEY, --該表也能夠有本身的主鍵。
        --該表的product_no字段爲上面products表主鍵(product_no)的外鍵。
        product_no integer REFERENCES products(product_no),
        quantity integer
    );
   
    CREATE TABLE t1 (
        a integer PRIMARY KEY,
        b integer,
        c integer,
        --該外鍵的字段數量和被引用表中主鍵的數量必須保持一致。
        FOREIGN KEY (b, c) REFERENCES example (b, c)
    );  
    當多個表之間存在了主外鍵的參考性約束關係時,若是想刪除被應用表(主鍵表)中的某行記錄,因爲該行記錄的主鍵字段值可能正在被其引用表(外鍵表)中某 條記錄所關聯,因此刪除操做將會失敗。若是想完成此操做,一個顯而易見的方法是先刪除引用表中和該記錄關聯的行,以後再刪除被引用表中的該行記錄。然而須要說明的是,PostgreSQL爲咱們提供了更爲方便的方式完成此類操做。
    CREATE TABLE products (
        product_no integer PRIMARY KEY,
        name text,
        price numeric
    );
    
    CREATE TABLE orders (
        order_id integer PRIMARY KEY,
        shipping_address text
    );
    
    CREATE TABLE order_items (
        product_no integer REFERENCES products ON DELETE RESTRICT, --限制選項
        order_id integer REFERENCES orders ON DELETE CASCADE, --級聯刪除選項
        quantity integer,
        PRIMARY KEY (product_no, order_id)
    );

    【限制和級聯刪除】是兩種最多見的選項。 sql

RESTRICT 禁止刪除被引用的行。 NO ACTION 的意思是若是在檢查約束的時候,若是還存在任何引用行,則拋出錯誤; 若是你不聲明任何東西,那麼它就是缺省的行爲。(這兩個選擇的實際區別是,NO ACTION 容許約束檢查推遲到事務的晚些時候,而 RESTRICT 不行。) 數據庫

CASCADE聲明在刪除一個被引用的行的時候,引用它的行也會被自動刪除掉。 在外鍵字段上的動做還有兩個選項: SET NULL 和 SET DEFAULT。 這樣會致使在被引用行刪除的時候,引用它們的字段分別設置爲空或者缺省值。 請注意這些選項並不能讓你逃脫被觀察和約束的境地。好比,若是一個動做聲明 SET DEFAULT,可是缺省值並不能知足外鍵,那麼動做就會失敗。相似ON DELETE,還有ON UPDATE 選項,它是在被引用字段修改(更新)的時候調用的。可用的動做是同樣的。 spa


2、系統字段:

    PostgreSQL的每一個數據表中都包含幾個隱含定義的系統字段。所以,這些名字不能用於用戶定義的字段名。這些系統字段的功能有些相似於Oracle中的rownum和rowid等。
     oid: 行的對象標識符(對象ID)。這個字段只有在建立表的時候使用了WITH OIDS,或者是設置了配置參數default_with_oids時出現。這個字段的類型是oid(和字段同名)。
     tableoid: 包含本行的表的OID。這個字段對那些從繼承層次中選取的查詢特別有用,由於若是沒有它的話,咱們就很難說明一行來自哪一個獨立的表。tableoid能夠和pg_class的oid字段鏈接起來獲取表名字。
     xmin: 插入該行版本的事務的標識(事務ID)。
     cmin: 在插入事務內部的命令標識(從零開始)。
     xmax: 刪除事務的標識(事務ID),若是不是被刪除的行版本,那麼是零。
     cmax: 在刪除事務內部的命令標識符,或者是零。
     ctid: 一個行版本在它所處的表內的物理位置。請注意,儘管ctid能夠用於很是快速地定位行版本,但每次VACUUM FULL以後,一個行的ctid都會被更新或者移動。所以ctid是不能做爲長期的行標識符的。   
    OID是32位的量,是在同一個集羣內通用的計數器上賦值的。對於一個大型或者長時間使用的數據庫,這個計數器是有可能重疊的。所以,假設OID是惟一 的是很是錯誤的,除非你本身採起了措施來保證它們是惟一的。若是你須要標識表中的行,咱們強烈建議使用序列號生成器。     
   
3、表的修改:

     1. 增長字段:
    ALTER TABLE products ADD COLUMN description text;
    新增的字段對於表中已經存在的行而言最初將先填充所給出的缺省值(若是你沒有聲明DEFAULT子句,那麼缺省是空值)。
    在新增字段時,能夠同時給該字段指定約束。
    ALTER TABLE products ADD COLUMN description text CHECK(description <> '');
    
    2. 刪除字段:
    ALTER TABLE products DROP COLUMN description;
    若是該表爲被引用表,該字段爲被引用字段,那麼上面的刪除操做將會失敗。若是要想在刪除被引用字段的同時級聯的刪除其全部引用字段,能夠採用下面的語法形式。
    ALTER TABLE products DROP COLUMN description CASCADE;
    
     3. 增長約束:
     ALTER TABLE products ADD CHECK(name <> '');  --增長一個表級約束
    ALTER TABLE products ADD CONSTRAINT some_name UNIQUE(product_no);--增長命名的惟一性約束。
    ALTER TABLE products ADD FOREIGN KEY(pdt_grp_id) REFERENCES pdt_grps; --增長外鍵約束。
    ALTER TABLE products ALTER COLUMN product_no SET NOT NULL; --增長一個非空約束。
    
     4. 刪除約束:
    ALTER TABLE products DROP CONSTRAINT some_name;
    對於顯示命名的約束,能夠根據其名稱直接刪除,對於隱式自動命名的約束,能夠經過psql的\d tablename來獲取該約束的名字。和刪除字段同樣,若是你想刪除有着被依賴關係地約束,你須要用CASCADE。一個例子是某個外鍵約束依賴被引用 字段上的惟一約束或者主鍵約束。如:
    MyTest=# \d products
         Table "public.products"
       Column     |  Type   | Modifiers
     ------------+---------+-----------
     product_no | integer |
     name          | text    |
     price           | numeric |
     Check constraints:
        "positive_price" CHECK (price > 0::numeric)
    和其餘約束不一樣的是,非空約束沒有名字,所以只能經過下面的方式刪除:
     ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
    
     5. 改變字段的缺省值:
    在爲已有字段添加缺省值時,不會影響任何表中現有的數據行, 它只是爲未來INSERT命令改變缺省值。
    ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
    下面爲刪除缺省值:
    ALTER TABLE products ALTER COLUMN price DROP DEFAULT
   
    6. 修改字段的數據類型:
    只有在字段裏現有的每一個項均可以用一個隱含的類型轉換轉換成新的類型時纔可能成功。好比當前的數據都是整型,而轉換的目標類型爲numeric或 varchar,這樣的轉換通常均可以成功。與此同時,PostgreSQL還將試圖把字段的缺省值(若是存在)轉換成新的類型, 還有涉及該字段的任何約束。可是這些轉換可能失敗,或者可能生成奇怪的結果。 在修改某字段類型以前,你最好刪除那些約束,而後再把本身手工修改過的添加上去。
    ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
       
     7. 修改字段名:
    ALTER TABLE products RENAME COLUMN product_no TO product_number;
    
     8. 修改表名:
    ALTER TABLE products RENAME TO items;
   
4、權限:

    只有表的全部者才能修改或者刪除表的權限。要賦予一個權限,咱們使用GRANT命令,要撤銷一個權限,使用REVOKE命令。
    須要指出的是,PUBLIC是特殊"用戶"能夠用於將權限賦予系統中的每個用戶。在聲明權限的位置寫ALL則將全部的與該對象類型相關的權限都賦予出去。
    GRANT UPDATE ON table_name TO user;  --將表的更新權限賦予指定的user。
    GRANT SELECT ON table_name TO GROUP group; --將表的select權限賦予指定的組。
    REVOKE ALL ON table_name FROM PUBLIC; --將表的全部權限從Public撤銷。
    最初,只有對象全部者(或者超級用戶)能夠賦予或者撤銷對象的權限。可是,咱們能夠賦予一個 "with grant option"權限,這樣就給接授權限的人以授予該權限給其它人的權限。若是授予選項後來被撤銷,那麼全部那些從這個接受者接受了權限的用戶(直接或者經過級連的受權)都將失去該權限。
相關文章
相關標籤/搜索