因?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)。。。
不轉(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ù)是不明智的。在WHERE和HAVING子句中依賴副作用或計(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ù) |