語意模型是「這段查詢的文字算出哪一份關係」這件事的規則。它只回答結果是什麼,不回答怎麼算到、要花多久。

規則的來源是關聯代數:每一個子句對應一個作用在關係上的運算,而查詢是那些運算的一個組合。代數是來源,語意模型是那套規則本身。

它與另外兩件事分開

與執行方式分開。 最佳化器可以任意重排步驟,只受一個約束:輸出的關係要與語意模型算出來的一致。這個分工是「代價由資料與索引決定、不由寫法決定」的根據(SQL.17 查詢的代價:資料分布、索引與寫法各自的影響)。

與書寫順序分開。 SELECT 寫在最前面而它在求值順序上排在後面,這正是語意模型與文字順序不同的地方(SQL.2 子句的求值順序:每一步可用的欄位、語意模型擋下的寫法與各家引擎放寬的寫法)。

它涵蓋的與它沒涵蓋的

模型定死的那些,換一家引擎不會變:三值邏輯讓條件的答案有第三種、外連接配不上時補 NULL、NOT IN 展開成一串連乘、分組把一組收成一列。三值邏輯、補 NULL 與 NOT IN 的展開在 SQL.6 連接之後的列數與空缺,分組在 SQL.9 分組鍵的選擇:鍵與一組所代表的對象。

模型之外另有幾件事在決定同一段查詢的結果:識別字被摺成什麼樣、引擎接不接受標準禁止的寫法並自己補一個值、送出這段 SQL 的人被允許讀哪些表。識別字在 SQL.14 識別字的規則:各家的大小寫摺疊、引號與保留字,引擎自己補值在 SQL.19 引擎寬鬆度與可攜性:各家對同一組寫法的差異、分級與處理時機,權限在 SQL.16 SQL 的權限模型:角色、GRANT 的授權單位與最小權限。這幾項與模型的差別是——模型的規則各家一致,這幾項不一致。

概念位置

「符合語意模型」與「答案對了」是兩件事。 模型與約束的分工也在這條線上——約束管資料能長成什麼樣,模型管那批資料算出什麼。 模型保證的是這段文字算出哪一批列,而那批列是不是要問的那個問題的答案,模型不管也管不到——問題不在查詢裡(SQL.13 查詢的合法性與答案的正確性:引擎檢查的範圍、答案錯掉的成因與查證方法)。講語意模型的那幾篇反覆出現的安靜錯誤——列數膨脹、外連接被抵銷、空值比較落空——全部發生在模型算對了的前提下。

往下走

規則的來源與封閉性在 Relational Algebra(關聯代數)。模型與書寫順序、執行順序怎麼分開,在 SQL.1 宣告式的紅利與代價。模型之外那幾方各決定什麼,在 Database Engine(資料庫引擎)。