PostgreSQL快捷手冊(cè)(有一般數(shù)據(jù)庫基礎(chǔ)前提下)

因?yàn)橛泻懿诲e(cuò)的Mysql和Oracle的底子就不寫那些無聊的了。

看了介紹后的感覺

一個(gè)有對(duì)象概念的關(guān)系型數(shù)據(jù)庫,與其說是關(guān)系型數(shù)據(jù)庫,倒不如說更像Elasticsearch那種NoSQL。他的對(duì)象觀念讓存的數(shù)據(jù)更加多元化了。我相信他在ORM上面應(yīng)該有更大的優(yōu)勢(shì),但是我目前也只是初見初步使用,暫時(shí)沒有看出來優(yōu)勢(shì)。

新特性

特別的數(shù)據(jù)類型

枚舉類型

有點(diǎn)類似oracle的賦值限制,不過建法不同。

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

幾何類型

神他瞄幾何類型,這個(gè)東西就是為了方便計(jì)算后期加入正式版的自定義類型吧。。。自己寫函數(shù)和自定義類型不好嗎,多此一舉,搞啥標(biāo)準(zhǔn)化。下面好多都是這樣的,看得人心累┓(;′_`)┏

名字 存儲(chǔ)空間 說明 表現(xiàn)形式
point 16 字節(jié) 平面中的點(diǎn) (x,y)
line 32 字節(jié) (無窮)直線(未完全實(shí)現(xiàn)) ((x1,y1),(x2,y2))
lseg 32 字節(jié) (有限)線段 ((x1,y1),(x2,y2))
box 32 字節(jié) 矩形 ((x1,y1),(x2,y2))
path 16+16n 字節(jié) 閉合路徑(與多邊形類似) ((x1,y1),...)
path 16+16n 字節(jié) 開放路徑 [(x1,y1),...]
polygon 40+16n 字節(jié) 多邊形(與閉合路徑相似) ((x1,y1),...)
circle 24 字節(jié) <(x,y),r> (圓心和半徑)

網(wǎng)絡(luò)地址類型

提供基本校驗(yàn)功能而已的文本

名字 存儲(chǔ)空間 描述
cidr 7 或 19 字節(jié) IPv4 或 IPv6 網(wǎng)絡(luò)
inet 7 或 19 字節(jié) IPv4 或 IPv6 主機(jī)和網(wǎng)絡(luò)
macaddr 6 字節(jié) MAC 地址

文本搜索類型

拆分文本?文本檢索?為嘛數(shù)據(jù)庫會(huì)來做這個(gè)操作?我懵逼了,我是難以理解這東西是干嘛的,難道能方便網(wǎng)頁做搜索功能?

UUID

標(biāo)準(zhǔn)基于RFC 4122,ISO/IEF 9834-8:2005

一般來說不做分布式是不會(huì)用的,還有是不是現(xiàn)代社會(huì)進(jìn)步了,都開始使用數(shù)據(jù)庫掌控?cái)?shù)據(jù)唯一性了。。。腦子大。

XML 類型

使用函數(shù) xmlparse: 來從字符數(shù)據(jù)產(chǎn)生 xml 類型的值:

XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')

JSON類型

json 數(shù)據(jù)類型可以用來存儲(chǔ) JSON(JavaScript Object Notation)數(shù)據(jù), 這樣的數(shù)據(jù)也可以存儲(chǔ)為 text,但是 json 數(shù)據(jù)類型更有利于檢查每個(gè)存儲(chǔ)的數(shù)值是可用的 JSON 值。

此外還有相關(guān)的函數(shù)來處理 json 數(shù)據(jù):

實(shí)例 實(shí)例結(jié)果
array_to_json('{{1,5},{99,100}}'::int[]) [[1,5],[99,100]]
row_to_json(row(1,'foo')) {"f1":1,"f2":"foo"}

數(shù)組類型

唯一一個(gè)我覺得不錯(cuò)的,畢竟原先我知道的只在procedure里面才支持?jǐn)?shù)組。還是很有用的(存?zhèn)€表不好嗎,寫這個(gè)數(shù)據(jù)庫的是不是太懶了!?)

CREATE TABLE sal_emp (
    name            text,
    pay_by_quarter  integer[],
    schedule        text[][]
);

復(fù)合類型

從這個(gè)開始就有對(duì)象的味道了,也有了ES的味道。這個(gè)其實(shí)就是struct

CREATE TYPE complex AS (
    r       double precision,
    i       double precision
);

CREATE TYPE inventory_item AS (
    name            text,
    supplier_id     integer,
    price           numeric
);

范圍類型

不能說沒用,寫這個(gè)數(shù)據(jù)庫的連設(shè)定個(gè)起止時(shí)間都不高興嗎?有毒,真的有。不過B-樹居然能利用到范圍變量里面去。。。我還是智商不行。

  • int4range — integer的范圍
  • int8range —bigint的范圍
  • numrange —numeric的范圍
  • tsrange —timestamp without time zone的范圍
  • tstzrange —timestamp with time zone的范圍
  • daterange —date的范圍

事務(wù)

默認(rèn)postgres是自動(dòng)開啟事務(wù)并提交的,挺討厭的,會(huì)導(dǎo)致誤操作。所以最好用戶自己去控制,并養(yǎng)成習(xí)慣:

BEGIN;
UPDATE accounts SET balance = balance - 100.00
    WHERE name = 'Alice';
SAVEPOINT my_savepoint;
UPDATE accounts SET balance = balance + 100.00
    WHERE name = 'Bob';
-- oops ... forget that and use Wally's account
ROLLBACK TO my_savepoint;
UPDATE accounts SET balance = balance + 100.00
    WHERE name = 'Wally';
COMMIT;

繼承

臥槽,繼承。。。。。。。。。行吧,你厲害

CREATE TABLE cities (
  name       text,
  population real,
  altitude   int     -- (in ft)
);

CREATE TABLE capitals (
  state      char(2)
) INHERITS (cities);

其實(shí)就是查詢父表會(huì)把子表帶出來輪一遍,可以用ONLY關(guān)鍵詞限制深入

寫法

U&""

16進(jìn)制Unicode字符

UESCAPE

將后面的字符當(dāng)做轉(zhuǎn)義字符看,默認(rèn)是''

'Dianne''s horse'

將兩個(gè)單引號(hào)看做文本本來有的單引號(hào)。。。

Dianne's horse

不轉(zhuǎn)義的方式

$$Dianne's horse$$
$SomeTag$Dianne's horse$SomeTag$

E'foo'

C風(fēng)格轉(zhuǎn)義的字符串常量

B'1001'或X'1FF'

二進(jìn)制或者十六進(jìn)制的位串常量

其他類型的變量

type 'string'
'string'::type
CAST ( 'string' AS type )

這其實(shí)是一個(gè)類型轉(zhuǎn)換

特殊字符

懶了,復(fù)制粘貼

一些不是數(shù)字字母的字符有一種不同于作為操作符的特殊含義。這些字符的詳細(xì)用法可以在描述相應(yīng)語法元素的地方找到。這一節(jié)只是為了告知它們的存在以及總結(jié)這些字符的目的。

  • 跟隨在一個(gè)美元符號(hào)($)后面的數(shù)字被用來表示在一個(gè)函數(shù)定義或一個(gè)預(yù)備語句中的位置參數(shù)。在其他上下文中該美元符號(hào)可以作為一個(gè)標(biāo)識(shí)符或者一個(gè)美元引用字符串常量的一部分。

  • 圓括號(hào)(())具有它們通常的含義,用來分組表達(dá)式并且強(qiáng)制優(yōu)先。在某些情況中,圓括號(hào)被要求作為一個(gè)特定 SQL 命令的固定語法的一部分。

  • 方括號(hào)([])被用來選擇一個(gè)數(shù)組中的元素。更多關(guān)于數(shù)組的信息見第 8.15 節(jié)。

  • 逗號(hào)(,)被用在某些語法結(jié)構(gòu)中來分割一個(gè)列表的元素。

  • 分號(hào)(;)結(jié)束一個(gè) SQL 命令。它不能出現(xiàn)在一個(gè)命令中間的任何位置,除了在一個(gè)字符串常量中或者一個(gè)被引用的標(biāo)識(shí)符中。

  • 冒號(hào)(:)被用來從數(shù)組中選擇“切片”(見第 8.15 節(jié))。在某些 SQL 的“方言”(例如嵌入式 SQL)中,冒號(hào)被用來作為變量名的前綴。

  • 星號(hào)(*)被用在某些上下文中標(biāo)記一個(gè)表的所有域或者組合值。當(dāng)它被用作一個(gè)聚集函數(shù)的參數(shù)時(shí),它還有一種特殊的含義,即該聚集不要求任何顯式參數(shù)。

  • 句點(diǎn)(.)被用在數(shù)字常量中,并且被用來分割模式、表和列名。

表 4.2. 操作符優(yōu)先級(jí)(從高到低)

操作符/元素 結(jié)合性 描述
. 表/列名分隔符
:: PostgreSQL-風(fēng)格的類型轉(zhuǎn)換
[ ] 數(shù)組元素選擇
+ - 一元加、一元減
^ 指數(shù)
* / % 乘、除、模
+ - 加、減
(任意其他操作符) 所有其他本地以及用戶定義的操作符
BETWEEN IN LIKE ILIKE SIMILAR 范圍包含、集合成員關(guān)系、字符串匹配
< > = <= >= <> 比較操作符
IS ISNULL NOTNULL IS TRUE、IS FALSE、IS NULL、IS DISTINCT FROM等
NOT 邏輯否定
AND 邏輯合取
OR 邏輯析取

值表達(dá)式

(compositecol).somefield

為嘛要加一個(gè)圓括號(hào)?因?yàn)樾枰拗芻ompositecol是一個(gè)列名而不是一個(gè)表名,下面則是則是顯示mytable是一個(gè)表名而不是一個(gè)模式名。
(mytable.compositecol).somefield

這其實(shí)是一個(gè)挺討人厭的性質(zhì)。正是因?yàn)閾碛凶远x類型導(dǎo)致整個(gè)結(jié)構(gòu)表述出現(xiàn)了一些特殊約定。

排序規(guī)則表達(dá)式

一個(gè)腦子大的關(guān)鍵詞,自己玩去吧

PostgreSQL 字符串 collate 與排序 源碼分析

行構(gòu)造器

ROW('fuzzy dice', 42, 1.99)

類似復(fù)合類型但是不能混用(他被叫做匿名混合類型),哈哈,具體可以看下文

CREATE TABLE mytable(f1 int, f2 float, f3 text);

CREATE FUNCTION getf1(mytable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;

-- 不需要造型因?yàn)橹挥幸粋€(gè) getf1() 存在
SELECT getf1(ROW(1,2.5,'this is a test'));
 getf1
-------
     1
(1 row)

CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);

CREATE FUNCTION getf1(myrowtype) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;

-- 現(xiàn)在我們需要一個(gè)造型來指示要調(diào)用哪個(gè)函數(shù):
SELECT getf1(ROW(1,2.5,'this is a test'));
ERROR:  function getf1(record) is not unique

SELECT getf1(ROW(1,2.5,'this is a test')::mytable);
 getf1
-------
     1
(1 row)

SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
 getf1
-------
    11
(1 row)

一個(gè)有趣的提示

子表達(dá)式的計(jì)算順序沒有被定義。特別地,一個(gè)操作符或函數(shù)的輸入不必按照從左至右或其他任何固定順序進(jìn)行計(jì)算。

此外,如果一個(gè)表達(dá)式的結(jié)果可以通過只計(jì)算其一部分來決定,那么其他子表達(dá)式可能完全不需要被計(jì)算。例如,如果我們寫:

SELECT true OR somefunc();

那么somefunc()將(可能)完全不被調(diào)用。如果我們寫成下面這樣也是一樣:

SELECT somefunc() OR true;

注意這和一些編程語言中布爾操作符從左至右的“短路”不同。

因此,在復(fù)雜表達(dá)式中使用帶有副作用的函數(shù)是不明智的。在WHEREHAVING子句中依賴副作用或計(jì)算順序尤其危險(xiǎn),因?yàn)樵诮⒁粋€(gè)執(zhí)行計(jì)劃時(shí)這些子句會(huì)被廣泛地重新處理。這些子句中布爾表達(dá)式(AND/OR/NOT的組合)可能會(huì)以布爾代數(shù)定律所允許的任何方式被重組。

當(dāng)有必要強(qiáng)制計(jì)算順序時(shí),可以使用一個(gè)CASE結(jié)構(gòu)(見第 9.17 節(jié))。例如,在一個(gè)WHERE子句中使用下面的方法嘗試避免除零是不可靠的:

SELECT ... WHERE x > 0 AND y/x > 1.5;

但是這是安全的:

SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;

一個(gè)以這種風(fēng)格使用的CASE結(jié)構(gòu)將使得優(yōu)化嘗試失敗,因此只有必要時(shí)才這樣做(在這個(gè)特別的例子中,最好通過寫y > 1.5*x來回避這個(gè)問題)。

不過,CASE不是這類問題的萬靈藥。上述技術(shù)的一個(gè)限制是, 它無法阻止常量子表達(dá)式的提早計(jì)算。如第 38.7 節(jié) 中所述,當(dāng)查詢被規(guī)劃而不是被執(zhí)行時(shí),被標(biāo)記成 IMMUTABLE的函數(shù)和操作符可以被計(jì)算。因此

SELECT CASE WHEN x > 0 THEN x ELSE 1/0 END FROM tab;

很可能會(huì)導(dǎo)致一次除零失敗,因?yàn)橐?guī)劃器嘗試簡化常量子表達(dá)式。即便是 表中的每一行都有x > 0(這樣運(yùn)行時(shí)永遠(yuǎn)不會(huì)進(jìn)入到 ELSE分支)也是這樣。

這個(gè)其實(shí)就是執(zhí)行計(jì)劃優(yōu)化的問題,和正常寫代碼的時(shí)候一樣,這都是很很常見的問題(例如編譯器優(yōu)化)

從修改的行中返回?cái)?shù)據(jù)

INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;

就這樣吧

名字 別名 描述
bigint int8 有符號(hào)的8字節(jié)整數(shù)
bigserial serial8 自動(dòng)增長的8字節(jié)整數(shù)
bit [ (n) ] 定長位串
bit varying [ (n) ] varbit [ (n) ] 變長位串
boolean bool 邏輯布爾值(真/假)
box 平面上的普通方框
bytea 二進(jìn)制數(shù)據(jù)(“字節(jié)數(shù)組”)
character [ (n) ] char [ (n) ] 定長字符串
character varying [ (n) ] varchar [ (n) ] 變長字符串
cidr IPv4或IPv6網(wǎng)絡(luò)地址
circle 平面上的圓
date 日歷日期(年、月、日)
double precision float8 雙精度浮點(diǎn)數(shù)(8字節(jié))
inet IPv4或IPv6主機(jī)地址
integer int, int4 有符號(hào)4字節(jié)整數(shù)
interval [ fields ] [ (p) ] 時(shí)間段
json 文本 JSON 數(shù)據(jù)
jsonb 二進(jìn)制 JSON 數(shù)據(jù),已分解
line 平面上的無限長的線
lseg 平面上的線段
macaddr MAC(Media Access Control)地址
macaddr8 MAC(Media Access Control)地址(EUI-64格式)
money 貨幣數(shù)量
numeric [ (p, s) ] decimal [ (p, s) ] 可選擇精度的精確數(shù)字
path 平面上的幾何路徑
pg_lsn PostgreSQL日志序列號(hào)
point 平面上的幾何點(diǎn)
polygon 平面上的封閉幾何路徑
real float4 單精度浮點(diǎn)數(shù)(4字節(jié))
smallint int2 有符號(hào)2字節(jié)整數(shù)
smallserial serial2 自動(dòng)增長的2字節(jié)整數(shù)
serial serial4 自動(dòng)增長的4字節(jié)整數(shù)
text 變長字符串
time [ (p) ] [ without time zone ] 一天中的時(shí)間(無時(shí)區(qū))
time [ (p) ] with time zone timetz 一天中的時(shí)間,包括時(shí)區(qū)
timestamp [ (p) ] [ without time zone ] 日期和時(shí)間(無時(shí)區(qū))
timestamp [ (p) ] with time zone timestamptz 日期和時(shí)間,包括時(shí)區(qū)
tsquery 文本搜索查詢
tsvector 文本搜索文檔
txid_snapshot 用戶級(jí)別事務(wù)ID快照
uuid 通用唯一標(biāo)識(shí)碼
xml XML數(shù)據(jù)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容