(Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.)
(IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.)
(THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.)
jolly=> insert into pg_group (groname, grosysid, grolist) jolly=> values ('posthackers', '1234', '{5443, 8261}'); INSERT 548224 jolly=> grant insert on foo to group posthackers; CHANGE jolly=>
pg_group 里的字段是:
groname:組名稱。這是一個名稱并且應該完全由字母和數字組成。不要包含下劃線和其他標點。 grosysid:組 id,這是一個 int4。應該在所有組中唯一。 grolist:屬于這個組的 pg_user id 的列表。這是一個 int4[]。
4.5) 你怎樣從一個表里面刪除一個列? 我們不支持 ALTER TABLE DROP COLUMN,但可以這樣做:
SELECT ... -- select all columns but the one you want to remove INTO TABLE new_table FROM old_table; DROP TABLE old_table; ALTER TABLE new_table RENAME TO old_table;
索引通常不用于 ORDER BY 操作:對一個大表的一次順序掃描然后跟著一個顯式的排序比對所有記錄的索引掃描要快,因為前者的磁盤訪問更少。
當使用模糊操作符,比如 LIKE 或 ~,只有在搜索的開始是掛在字串的開頭部分時才用得到索引。因而要使用索引,LIKE 搜索不應該以 % 開頭,而~(規則表達式搜索)應該以^ 開頭。
4.10) 我如何才能看到查詢優化器是怎樣計算我的查詢的? 參考 EXPLAIN 手冊頁。
4.11) R-tree 索引是什么? r-tree 索引用于索引空間數據。一個哈希索引無法處理范圍搜索。而 B-tree 索引只能處理一維的范圍搜索。R-tree 索引可以處理多維數據。例如,如果可以在一個類型為 point 的字段上建立一個 R-tree 索引,那么系統在回答類似 select all points within a bounding rectangle (選擇在一個長方形范圍內的所有點)這樣的查詢時有更高的效率。
描述最初的 R-Tree 的設計的規范里面寫到:
Guttman, A. "R-Trees: A Dynamic Index Structure for Spatial Searching." Proc of the 1984 ACM SIGMOD Int'l Conf on Mgmt of Data, 45-57.
你還可以在 Stonebraker 的 "Readings in Database Systems" 找到這篇文章。
4.14) 在一個查詢里,我怎樣檢測一個字段是否為 NULL? 你用 IS NULL 和 IS NOT NULL 測試這個字段。
4.15) 各種字符類型之間有什么不同? Type Internal Name Notes -------------------------------------------------- "char" char 1 character CHAR(#) bpchar blank padded to the specified fixed length VARCHAR(#) varchar size specifies maximum length, no padding TEXT text length limited only by maximum row length BYTEA bytea variable-length array of bytes
4.16.1) 我怎樣創建一個序列號/自動遞增的字段? PostgreSQL 支持 SERIAL 數據類型。它在字段上自動創建一個序列和索引。例如,這樣...
CREATE TABLE person ( id SERIAL, name TEXT );
...會自動轉換為這樣...
CREATE SEQUENCE person_id_seq; CREATE TABLE person ( id INT4 NOT NULL DEFAULT nextval('person_id_seq'), name TEXT ); CREATE UNIQUE INDEX person_id_key ON person ( id );
參考 create_sequence 手冊頁獲取關于序列的更多信息。你還可以用每行的 oid 字段作為一個唯一值。不過,如果你需要傾倒和重載數據庫,你需要使用 pg_dump 的 -o 選項或者 COPY WITH OIDS 選項以保留 oid。
更多信息,參閱 Bruce Momjian 的 行計數 章節。
4.16.2) 我如何獲得一個插入后生成的序列號( SERIAL )的值? 可能實現這個要求的最簡單的方法是:在插入之前先用函數 nextval() 從序列對象里檢索出下一個 SERIAL 值,然后再顯式插入。利用 4.16.1 里的例子表,這樣做看起來象下面這樣:
$newSerialID = nextval('person_id_seq'); INSERT INTO person (id, name) VALUES ($newSerialID, 'Blaise Pascal');
你還能獲得存儲在 $newSerialID 里面的新值,可以用于其他查詢(例如,作為 person 表的外鍵)。要注意自動創建的 SEQUENCE 對象的名稱將會是命名為
__seq,這里 table 和 serialcolumn 分別是你的表的名稱和你的 SERIAL 字段的名稱。
類似的,在 SERIAL 對象缺省插入后你可以用函數 currval() 檢索剛賦值的 SERIAL 值,例如,
INSERT INTO person (name) VALUES ('Blaise Pascal'); $newID = currval('person_id_seq');
最后,你可以使用從 INSERT 語句返回的 oid 查找缺省值,盡管這可能是最缺乏移植性的方法。在 perl 里,使用帶有 Edmund Mergl 的 DBD::Pg 模塊的 DBI,oid 值可以通過 $sth->execute() 后的 $sth->{pg_oid_status} 獲得。
4.17) 什么是 oid?什么是 tid? Oid 是 PostgreSQL 的唯一行標識。PostgreSQL 里創建的每一行都獲得一個唯一的 oid。所有在 initdb 過程中創建的 oid 都小于 16384 (來自 backend/access/transam.h)。所有用戶創建的 oid 都大于或等于這個值。缺省時,所有這些 oid 不僅在一個表,一個數據庫里面唯一,而且在整個 PostgreSQL 安裝里也是唯一的。
PostgreSQL 在它的內部系統表里使用 oid 在表之間聯接行。這些 oid 可以用于標識特定的用戶行以及用在聯合里。我們建議你使用字段類型 oid 存儲 oid 值。參閱 sql(l) 手冊頁查找其他內部字段。你可以在 oid 字段上創建一個索引以獲取快速訪問。
Oid 從被所有數據庫使用的某個區域里賦值給所有新行。如果你想把 oid 該成別的值,或者你想做一份表的帶著原始 oid 的拷貝,你可以做到:
CREATE TABLE new_table(old_oid oid, mycol int); SELECT INTO new SELECT old_oid, mycol FROM old; COPY new TO '/tmp/pgtable'; DELETE FROM new; COPY new WITH OIDS FROM '/tmp/pgtable';
Tid 用于標識帶著數據塊和偏移量值的特定的物理行。Tid 在每行的更改或者重載后被改變。它們被索引記錄用于指引物理行。