<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # <span style="font-size:15px">**擴展的基本定義** </span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;postgresql將多個SQL對象(如新函數、新操作符或新的索引操作符)收集到一個單一的包中,這種單一包有助于簡化數據庫的使用和管理,postgresql稱這樣單一的包為擴展。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;擴展的定義至少需要一個包含創建該擴展的對象的SQL命令的腳本文件以及一個指定擴展本身的一些基本屬性的*控制文件*。如果擴展包括 C 代碼,通常還有一個 C 代碼編譯而成的共享庫文件。有了這些文件,則可以通過`CREATE EXTENSION`命令將這些對象加載進數據庫中。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;擴展機制也對打包調整一個擴展中所含 SQL 對象定義的修改腳本有規定。例如,如果一個擴展的 1.1 版本比 1.0 版本增加了一個函數并且更改了另一個函數的函數體,該擴展的作者可以提供一個更新腳本來做這兩個更改。那么`ALTER EXTENSION UPDATE`命令可以被用來應用這些更改并且跟蹤在給定數據庫中實際安裝的是該擴展的哪個版本。 # <span style="font-size:15px">**重要概念** </span> * 擴展只在一個數據庫范圍內可見,因此數據庫集簇范圍的對象(例如數據庫、角色和表空間)不能作為擴展成員;雖然一個表可以是一個擴展的成員,它的輔助對象(例如索引)不會被直接認為是該擴展的成員。因此不能通過`ALTER EXTENSION`命令進行更改 * 模式可以屬于擴展,但是擴展不屬于模式,擴展所對應的模式也可以通過`ALTER EXTENSION`命令進行更改 ``` // 查看當前已安裝的擴展及其對應的模式 postgres=# SELECT e.oid,e.extname,n.nspname from pg_extension e JOIN pg_namespace n on e.extnamespace = n.oid; oid | extname | nspname -------+--------------------+------------ 13566 | plpgsql | pg_catalog 16439 | first_last_agg | public 16446 | pg_trgm | public 16540 | pg_freespacemap | public 16555 | pg_visibility | public 16565 | pg_stat_statements | public (6 rows) ``` # <span style="font-size:15px">**擴展的優點** </span> * 擴展的使用不只是運行SQL腳本載入這些“松散”的對象到數據庫,而是postgresql可以將這個擴展的成員對象理解為“一個整體”,因此也可以使用單一的`DROP EXTENSION`命令刪除指定擴展的所有對象,而不需要單獨去維護單個對象的刪除卸載 * 可將業務查詢中高頻使用的業務語句或復雜字段處理方式封裝成擴展進行使用,就可以像內置的特性一樣在數據庫中運行,避免重復造輪子。 * 支持擴展的版本升級以及擴展中的SQL命令的更新 # <span style="font-size:15px">**擴展的基本組成** </span> * demo--1.0.sql * 對自定義函數的聲明,在pgsql啟動的時候會執行這個sql。文件命名遵循:`extension--version.sql`(例如:demo--1.0.sql表示擴展demo的1.0版本) * 默認情況下,腳本文件也被放置在`SHAREDIR/extension`目錄中,但是控制文件中可以為腳本文件指定一個不同的目錄 * SQL腳本文件能夠包含任何 SQL 命令,除了事務控制命令(`BEGIN`、`COMMIT`等)以及不能在一個事務塊中執行的命令(如`VACUUM`)。這是因為腳本文件會被隱式地在一個事務塊中被執行 * demo.c:自定義函數的實現,純C語言,目錄下可包含多個.c文件。 * demo.control * `CREATE EXTENSION` 命令依賴每一個擴展都有的控制文件,控制文件必須被命名為擴展的名稱加上一個后綴`.control`,并且必須被放在安裝的`SHAREDIR/extension`目錄中 * demo-1.0.control * 二級控制文件,以`extension--version.control`的風格命名 ,二級控制文件遵循主要控制文件相同的格式。 * 在安裝或更新該擴展的版本時,一個二級控制文件中設置的任何參數將覆蓋主要控制文件中的設置,參數`directory`以及`default_version`不能在二級控制文件中設置。 * Makefile:編譯文件 ``` [postgres@izwz91quxhnlkan8kjak5hz contrib]$ ls btree_gin btree_gin--1.0--1.1.sql btree_gin--1.0.sql btree_gin--1.1--1.2.sql btree_gin--1.2--1.3.sql btree_gin.c btree_gin.control expected Makefile sql ``` ## <span style="font-size:15px">**.control文件基本格式** </span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一個擴展控制文件的格式與`postgresql.conf`文件相同,即是一個`parameter_name = value`賦值的列表,每行一個。允許空行和`#`引入的注釋。注意對任何不是單一詞或數字的值加上引號。 控制文件可以設置下列參數: * **directory(string)**:包含擴展的SQL腳本文件的目錄。除非給出一個絕對路徑,這個目錄名是相對于安裝的`SHAREDIR`目錄。默認行為等效于指定`directory = extension` * **default_version(string)**:擴展的默認版本,如果`create extension`中沒有指定,將默認使用這個參數 * **comment(string)**:關于該擴展的注釋。該注釋會在初始創建擴展時應用,但是擴展更新時不會引用該注釋(因為可能會覆蓋用戶增加的注釋)。擴展的注釋也可以通過在腳本文件中寫上[COMMENT](http://postgres.cn/docs/13/sql-comment.html "COMMENT")命令來設置。 * **encoding(string)**:該腳本文件使用的字符集編碼。當腳本文件包含任何非 ASCII 字符時,可以指定這個參數。否則文件都會被假定為數據庫編碼。 * **module_pathname(string)**:該參數告訴PG在執行到用戶自定義函數的時候去這個路徑下找庫文件。 * **requires(string):** 這個擴展依賴的其他擴展名的一個列表,例如`requires = 'foo, bar'`。被依賴的擴展必須先于這個擴展安裝 * **superuser(boolean)**:默認情況下為true,只有超級用戶能夠創建該擴展或者將它更新到一個新版本 * **trusted(boolean)**:默認值為false,如果設置為true,則允許非超級管理員權限的用戶安裝superuser已設置為true的擴展,即對于在當前數據庫上具有`CREATE`特權的任何人,都允許安裝。 當執行`CREATE EXTENSION`的用戶不是超級用戶,但允許通過此參數安裝時,則此安裝或更新腳本作為引導超級用戶運行,而不是作為調用用戶 * **relocatable(boolean)**:擴展的可再定位性,如果支持擴展能被重定位到另一個模式則為true,默認為false。三種支持的可定位性級別: * 一個完全可重定位的擴展能在任何時候被移動到另一個模式中,即使在它被載入到一個數據庫中之后。這種移動通過`ALTER EXTENSION SET SCHEMA`命令完成,該命令會自動地把所有成員對象重命名到新的模式中,它的控制文件中需要設置`relocatable = true` * 一個擴展可能在安裝過程中是可重定位的,但是安裝完后就不再可重定位。典型的情況是擴展的腳本文件需要顯式地引用目標模式,例如為 SQL 函數設置`search_path`屬性。對于這樣一種擴展,在其控制文件中設置`relocatable = false`,并且使用`@extschema@`在腳本文件中引用目標模式。在腳本被執行前,所有這個字符串的出現都將被替換為實際的目標模式名。用戶可以使用`CREATE EXTENSION`的`SCHEMA`選項設置目標模式名。 * 如果擴展根本就不支持重定位,在它的控制文件中設置`relocatable = false`,并且還設置`schema`為想要的目標模式的名稱。這將阻止使用`CREATE EXTENSION`的`SCHEMA`選項修改目標模式,除非它指定的是和控制文件中相同的模式。如果該擴展包括關于模式名的內部假設且模式名不能使用`@extschema@`的方法替換,這種選擇通常是必須的。`@extschema@`替換機制在這種情況中也是可用的,不過由于模式名已經被控制文件所決定,它的使用受到了很大的限制。 * **schema(string) :** 這個參數只能為非可重定位擴展設置。它強制擴展被載入到給定的模式中而非其他模式中。只有在初始創建一個擴展時才會參考`schema`參數,擴展更新時則不會參考這個參數 > **控制文件參數補充說明:** > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、關于`relocatable`,所有的情況下,腳本文件將被用[search\_path](http://postgres.cn/docs/13/runtime-config-client.html#GUC-SEARCH-PATH)執行,它會被設置為指向目標模式,也就是說`CREATE EXTENSION`做的也是等效的工作:`SET LOCAL search_path TO @extschema@, pg_temp;` > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、如果控制文件中給出了`schema`參數,目標模式就由該參數決定,否則目標模式由`CREATE EXTENSION`的`SCHEMA`選項給出,如果以上兩者都沒有給出則會用當前默認的對象創建模式(在調用者`search_path`中的第一個)。當使用擴展文件的`schema`參數時,如果目標模式還不存在將創建它,但是在另外兩種情況下它必須已經存在。 > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、如果在控制文件中的`requires`中列舉了任何先導擴展,它們的目標模式會被追加到`search_path`的初始設置中,遵循新擴展的目標模式。 這允許新擴展的腳本文件能夠看到它們的對象。 ``` [postgres@izwz91quxhnlkan8kjak5hz contrib]$ cat btree_gin/btree_gin.control # btree_gin extension comment = 'support for indexing common datatypes in GIN' default_version = '1.3' module_pathname = '$libdir/btree_gin' relocatable = true trusted = true ``` ## <span style="font-size:15px">**Makefile文件基本格式** </span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;postgresql為擴展的安裝提供了一種被稱為PGXS的構建基礎設施,因此簡單的擴展模塊能夠在一個已經安裝的服務器上簡單地編譯。PGXS基礎設施需要應用于擴展的Makefile文件中,這三行總是相同的: ``` EXTENSION = demo # 擴展名稱 DATA = demo--1.0.sql # 擴展安裝的sql腳本文件 # pgsql構建擴展的相關命令,固定即可,無需更改 PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) ``` # <span style="font-size:15px">**擴展版本更新機制** </span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可以通過擴展的安裝腳本的每一個發行版本關聯一個版本名稱或者版本號來實現動態的將數據庫從一個版本更新到下一個版本,腳本的名稱遵循`extension--old_version--target_version.sql`模式 (例如`demo--1.0--1.1.sql`包含著把擴展`demo`的版本`1.0`修改成版本`1.1`的命令) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;命令`ALTER EXTENSION UPDATE`可以將把一個已安裝的擴展更新到指定的新版本。此外,此命令能夠根據更新腳本的版本序列實現版本更新,例如只有`demo--1.0--1.1.sql`和`demo--1.1--2.0.sql`可用,當前安裝了`1.0`版本并且要求更新到版本`2.0`,`ALTER EXTENSION` 命令將將依次應用它們。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostgreSQL不對更新腳本的版本名稱的屬性做任何假設,例如`demo--1.0--1.1.sql`,它不知道是否`1.1`遵循`1.0`,它只是匹配可用的版本名稱并遵循需要應用最少更新腳本的路徑。(版本名稱實際上可以是不包含`--`或前綴或后綴的任何字符串`-`) > **Q:** 那么問題就來了,pgsql無法識別更新腳本的命名規范是否真實有效,是如何通過匹配可用的版本名稱來搜索出可用的更新腳本的**最短路徑**? > **A:** 通過pgsql的內置系統函數`pg_extension_update_paths`來檢索擴展版本之間的可用更新路徑。 ``` // pg_extension_update_paths 函數輸出顯示了擴展版本的每個組合,以及從source版本升級到目標版本時將執行的擴展腳本組合 // 如果路徑為空,則無法升級 postgres=# SELECT * FROM pg_extension_update_paths('first_last_agg'); source | target | path ------------+------------+----------------------------------------------- 0.1.4 | 0.1.2 | 0.1.4 | 0.1.3 | 0.1.4 | 0.1.1 | 0.1.4 | unpackaged | 0.1.4 | 0.1.0 | 0.1.2 | 0.1.4 | 0.1.2--0.1.3--0.1.4 0.1.2 | 0.1.3 | 0.1.2--0.1.3 0.1.2 | 0.1.1 | 0.1.2 | unpackaged | 0.1.2 | 0.1.0 | 0.1.3 | 0.1.4 | 0.1.3--0.1.4 0.1.3 | 0.1.2 | 0.1.3 | 0.1.1 | 0.1.3 | unpackaged | 0.1.3 | 0.1.0 | 0.1.1 | 0.1.4 | 0.1.1--0.1.2--0.1.3--0.1.4 0.1.1 | 0.1.2 | 0.1.1--0.1.2 0.1.1 | 0.1.3 | 0.1.1--0.1.2--0.1.3 0.1.1 | unpackaged | 0.1.1 | 0.1.0 | unpackaged | 0.1.4 | unpackaged--0.1.0--0.1.1--0.1.2--0.1.3--0.1.4 unpackaged | 0.1.2 | unpackaged--0.1.0--0.1.1--0.1.2 unpackaged | 0.1.3 | unpackaged--0.1.0--0.1.1--0.1.2--0.1.3 unpackaged | 0.1.1 | unpackaged--0.1.0--0.1.1 unpackaged | 0.1.0 | unpackaged--0.1.0 0.1.0 | 0.1.4 | 0.1.0--0.1.1--0.1.2--0.1.3--0.1.4 0.1.0 | 0.1.2 | 0.1.0--0.1.1--0.1.2 0.1.0 | 0.1.3 | 0.1.0--0.1.1--0.1.2--0.1.3 0.1.0 | 0.1.1 | 0.1.0--0.1.1 0.1.0 | unpackaged | (30 rows) ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;postgresql并不對更新腳本的版本名稱的屬性做任何假設,因此即可以實現版本升級,也可以實現“版本降級”,例如,將腳本命名為`demo--1.1--1.0.sql`。降級更新可能會導致的問題在于,降級腳本存在被意外使用的可能性,因為降級腳本會得到一個較短的路徑,如果降級版本刪除了任何不可替代的對象,這將會得到意想不到的結果。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一個已經存在一段時間的擴展可能存在多個版本。例如,如果你已經發布了擴展`demo`的`1.0`、`1.1`和`1.2`版本,就應該有更新腳本`demo--1.0--1.1.sql`和`demo--1.1--1.2.sql`。`CREATE EXTENSION`能夠自動遵循更新鏈。例如,如果只有腳本文件`demo--1.0.sql`、`demo--1.0--1.1.sql`和`demo--1.1--1.2.sql`可用,那么安裝版本`1.2`的請求會通過按順序運行上述三個腳本來實現。這種處理和先安裝`1.0`然后更新到`1.2`是一樣的(和`ALTER EXTENSION UPDATE`一樣,如果有多條路徑可用則優先選擇最短的) > 在PostgreSQL10之前,還有必要創建新的腳本文件`demo--1.1.sql`和`demo--1.2.sql`,它們直接構建比較新的擴展版本,或者新的版本無法被直接安裝,而是通過先安裝`1.0`然后更新 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果以這種風格維護的擴展中使用了二級(版本相關的)控制文件,記住每個版本都需要一個控制文件,即使它沒有單獨的安裝腳本,因為該控制文件將決定如何執行到這個版本的隱式更新。例如,如果`demo--1.0.control`指定有`requires = 'bar'`,但`demo`的其他控制文件沒有這樣做,在從`1.0`更新到另一個版本時,該擴展對`bar`的依賴將被刪除。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看