《PostgreSQL 三價邏輯詳解》要點:
本文介紹了PostgreSQL 三價邏輯詳解,希望對您有用。如果有疑問,可以聯(lián)系我們。
相關(guān)主題:PostgreSQL教程
更多深度文章,請關(guān)注云計算頻道:https://yq.aliyun.com/cloud
背景
在邏輯運(yùn)算中有三種狀態(tài)表示,真、假、不知道.
數(shù)據(jù)庫的NULL表示沒有值, 空的意思(在邏輯中屬于 不知道).
在三價邏輯運(yùn)算中, 數(shù)據(jù)庫的NULL相當(dāng)于UNKNOWN的意思.
三價邏輯運(yùn)算請參考 :
http://en.wikipedia.org/wiki/Three-valued_logic
來看看三價邏輯運(yùn)算的真值表 :
Kleene logic
Below is a set of truth tables showing the logic operations for Kleene's logic.
A AND B | True | Unknown | False |
---|---|---|---|
True | True | Unknown | False |
Unknown | Unknown | Unknown | False |
False | False | False | False |
A OR B | True | Unknown | False |
---|---|---|---|
True | True | True | True |
Unknown | True | Unknown | Unknown |
False | True | Unknown | False |
A | NOT A |
---|---|
True | False |
Unknown | Unknown |
False | True |
Lukasiewicz logic真值表略...
簡單的解釋一下, 在這里Unknown可能是true也可能是false.
因此 :
對于Unknown and true 可能是true and true也可能是false and true. 那么結(jié)果應(yīng)該是true或者false. 最終還是不確定. 所以還是Unknown.
對于NOT Unknown. 也一樣, 可能是NOT true也可能是NOT false, 結(jié)果有可能是true或者false, 最終還是不確定, 所以還是Unknown.
對于Unknown or true, 不管Unknown是true還是false, 結(jié)果都是true.
對于Unknown and false, 不管Unknown是true還是false, 結(jié)果都是false.
對于Unknown and Unknown, 可能是true and true或者true and false或者false and false最終結(jié)果不確定, 所以還是Unknown.
對于Unknown or Unknown, 可能是true or true或者true or false或者false or false最終結(jié)果不確定, 所以還是Unknown.
在PostgreSQL數(shù)據(jù)庫中是如何處理的呢?
正文
驗證以上真值表(僅驗證含null的部分) :
ocz@db-172-16-3-150-> psql digoal
接下來測試where條件中的null.
digoal=# select 1 where null;
從測試結(jié)果可以看出WHERE子句中的 null和false一樣, 被排除掉了.
接下來測試數(shù)據(jù)庫基本的比較操作中用到null的地方的運(yùn)算結(jié)果.
Operator | Description |
---|---|
< | less than |
> | greater than |
<= | less than or equal to |
>= | greater than or equal to |
= | equal |
<> or != | not equal |
以上操作符只要帶有null的比較返回值都是null.
例如 :
digoal=# select 1 < null;
表示不知道null和null是否相等, 所以輸出還是null.
digoal=# select null=null;
表示不知道null和null是否不相等, 所以輸出還是null.
digoal=# select null <> null;
between and 相當(dāng)于>= and <=, 例如 :
digoal=# select 1 between null and null;
not between and 相當(dāng)于 < or >, 例如 :
digoal=# select null not between 1 and null;
2. case, 注意CASE中如果使用NULL, 是使用的=操作符. 所以null分支用于不會執(zhí)行. 如下 :
digoal=# select case 1 when null then 'is null' else 'is not null' end;
其他表達(dá)式中的null :
表示不知道null+1等于多少, 結(jié)果輸出還是null.
postgres=# select null+1;
注意
1. SQL中的特例, 某些使用場景中null和null被認(rèn)為是相同的, 這打破了三價邏輯的規(guī)則. 如下.
postgres=# select null union select null;
2. 聚合函數(shù), 除了count(*) 其他聚合函數(shù)都不處理null值. 例如 :
Table
i | j |
---|---|
150 | 150 |
200 | 200 |
250 | 250 |
NULL | 0 |
Here AVG(i) is 200 (the average of 150, 200, and 250), while AVG(j) is 150 (the average of 150, 200, 250, and 0).
A well-known side effect of this is that in SQL AVG(z) is not equivalent with SUM(z)/COUNT(*).
聚合函數(shù)注意, 如果傳入了distinct的話, 就要看函數(shù)的strict標(biāo)記 :
* Aggregate functions that are called with DISTINCT are now passed
3. 在SQL92標(biāo)準(zhǔn)擴(kuò)展文件F571定義了6個操作符, 僅返回true或false, 不返回unknown如下 :
p | true | false | unknown |
---|---|---|---|
p IS TRUE | true | false | false |
p IS NOT TRUE | false | true | true |
p IS FALSE | false | true | false |
p IS NOT FALSE | true | false | true |
p IS UNKNOWN | false | false | true |
p IS NOT UNKNOWN | true | true | false |
digoal=# select null is true;
4. 除此之外, PostgreSQL 中還包含兩個邏輯操作符.
IS DISTINCT FROM 和 IS NOT DISTINCT FROM, 所有操作都返回true或者false, 不會返回null :
Ordinary comparison operators yield null (signifying "unknown"), not true or false, when either input is null.
digoal=# select null is distinct from null;
5. PostgreSQL transform_null_equals參數(shù)打開, 將'表達(dá)式=null'或'null=表達(dá)式'轉(zhuǎn)換成'表達(dá)式 is null'. 如下 :
digoal=# set transform_null_equals=on;
注意這個參數(shù)不影響case表達(dá)式的判斷, 和修改前結(jié)果一致 :
digoal=# select case null when null then 'is null' else 'is not null' end;
6. greatest和least不處理null值.
digoal=# select greatest(null,null);
7. 索引中的null值, PostgreSQL 8.3以前(不含8.3)的版本的BTREE索引不支持IS NULL的查詢.
參見 HISTORY :
* Allow col IS NULL to use an index (Teodor)
參考
1. http://en.wikipedia.org/wiki/Null_(SQL)
2. http://en.wikipedia.org/wiki/Three-valued_logic
3. http://www.databasedesign-resource.com/null-values-in-a-database.html
4. http://en.wikipedia.org/wiki/Propositional_logic
5. http://en.wikipedia.org/wiki/%C5%81ukasiewicz_logic
6. http://en.wikipedia.org/wiki/Stephen_Cole_Kleene
7. http://link.springer.com/chapter/10.1007%2F3-540-36596-6_7
8. http://www.postgresql.org/docs/9.2/static/functions-comparison.html
《PostgreSQL 三價邏輯詳解》是否對您有啟發(fā),歡迎查看更多與《PostgreSQL 三價邏輯詳解》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/9629.html