上一篇介紹了文氏圖與 SQL 的集合的應用,這一篇要介紹的是歐拉圖,歐拉圖與文氏圖不同之處,在於它主要不是用來顯示交集關係的。
來看看下面兩張圖:
上圖它呈現了三個集合之間有包含的關係,房子包含 A 房間包含手機,這之間都沒有任何交集關係。
上圖它呈現了一整個空間中有成功和非成功的分期付款資訊,主要要查詢的部分有 2015 - 2017 的年度刷卡資料,裡面有個年度、月份的資料子集合。
這一篇想要介紹歐拉圖與集合論推理的兩個重要的觀點,假設集合之間都是包含關係:
1. 小的集合存在你需要的資料,那麼大的集合也會有那筆資料。
2. 大的集合中不存在你需要的資料,那麼小的集合也不會有那筆資料。
聽起來很合理,而希望分享這件事的原因,是因為以前在學分析的時候,寫證明時很常使用到這樣的概念來推理函數收斂、發散,亦或是推理的性質,而進了職場工作後,時常在做資料檢查與分析的事,即便是使用這樣簡單的概念去推理資訊給交付者,也可以省下很多時間 (前提是對方要知道)。
在目前解決問題的系統中,你有一張 Orders
(訂單) 表和 Installments
(分期) 表,表示一筆訂單有多筆分期,分期資料會放在 Installemts
。
CREATE TABLE `orders` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(256) NULL,
`createdAt` TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (`id`));
CREATE TABLE `installments` (
`id` INT NOT NULL AUTO_INCREMENT,
`expectInstallAt` DATETIME NOT NULL,
`successfulInstallAt` DATETIME NULL,
`OrderId` INT NOT NULL,
PRIMARY KEY (`id`));
每一筆 Installemts
對應 Orders
是多 (筆分期) 對一 (個訂單) 的關係,此時你已知 Installmets
是最大的集合,包含 Order
較小數量的集合。
現在,你的手上有一個 Order
的表以及分期的 Installment
(分期) 表,而你的主管正在懷疑某個訂單 (order) 資料是否缺失,於是你現在檢查了 Installments
任一筆資料是否 【找不到】 對應的 Orders
。
Installments 表:
Orders 表:
透過查詢指令尋找兩個表的資料是否有對上:
SELECT * FROM installments i
LEFT JOIN orders o ON o.id = i.OrderId
WHERE o.id IS NULL;
結果發現有一筆資料在 LEFT JOIN 之後真的沒有 Orders (右側被 JOIN 出來是 NULL):
此時,你可以很肯定無論怎樣,這筆 Order Id 為 3 的資料已經缺失,找不到了,所以就算你到 Order 資料表中尋找或用其他方法 Join,也不會找到這筆資料。
這個就是 【2. 大的集合中不存在你需要的資料,那麼小的集合也不會有那筆資料】
現在,你收到了一筆資料,告訴你 InstallmentId 大集合與 OrderId 其中某一筆存在:
那也可以保證,Installments 這張表一定存在這筆 Order 的連結,這就是 【小的集合存在你需要的資料,那麼大的集合也會有那筆資料】,但反過來說,如果小的集合不存在你需要的資料,不代表大的集合不存在那筆資料。
換一題,你擔心 2017 年某一張 Order 是否缺失所有 Installments 分期付款資訊,所以,檢查 Installments (分期) 的目標是: 是否有任何一筆分期綁到這張指定的訂單,所以你寫了查詢:
SELECT COUNT(*) FROM installments i WHERE i.OrderId = 3 AND YEAR(i.expectInstallAt) = 2017;
這個查詢回傳了結果:
雖然結果表示這筆訂單是有 1 筆分期資料的,但是無法保證 installments 資料是完整的,這個就表示了,如果你有 2 筆資料,而你目前找到了一筆,就表示了【小的集合 (2017 年的集合) 存在你需要的資料,但不代表所有的集合都找得到另外一筆】。
這篇文章寫的是集合使用的圖表以及解釋邏輯的部分,寫起來頗難臨時創造一個好的例子解釋。
References:
[1] https://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%9B%BE