iT邦幫忙

2021 iThome 鐵人賽

DAY 10
1
自我挑戰組

後端工程師與圖的修練系列 第 10

集合推理與歐拉圖

  • 分享至 

  • xImage
  •  

上一篇介紹了文氏圖與 SQL 的集合的應用,這一篇要介紹的是歐拉圖,歐拉圖與文氏圖不同之處,在於它主要不是用來顯示交集關係的。

來看看下面兩張圖:

https://ithelp.ithome.com.tw/upload/images/20210920/20092753Wi5wLBsMCf.png

上圖它呈現了三個集合之間有包含的關係,房子包含 A 房間包含手機,這之間都沒有任何交集關係。

https://ithelp.ithome.com.tw/upload/images/20210920/20092753kqGgjmzguw.png

上圖它呈現了一整個空間中有成功和非成功的分期付款資訊,主要要查詢的部分有 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 較小數量的集合。

https://ithelp.ithome.com.tw/upload/images/20210920/20092753t1nH1Ufqtc.png

現在,你的手上有一個 Order 的表以及分期的 Installment (分期) 表,而你的主管正在懷疑某個訂單 (order) 資料是否缺失,於是你現在檢查了 Installments 任一筆資料是否 【找不到】 對應的 Orders

Installments 表:
https://ithelp.ithome.com.tw/upload/images/20210920/20092753XUwDS2FibQ.png

Orders 表:
https://ithelp.ithome.com.tw/upload/images/20210920/20092753WPcaiQVfmX.png

透過查詢指令尋找兩個表的資料是否有對上:

SELECT * FROM installments i
LEFT JOIN orders o ON o.id = i.OrderId
WHERE o.id IS NULL;

結果發現有一筆資料在 LEFT JOIN 之後真的沒有 Orders (右側被 JOIN 出來是 NULL):
https://ithelp.ithome.com.tw/upload/images/20210920/20092753zsj6iMw3Hn.png

此時,你可以很肯定無論怎樣,這筆 Order Id 為 3 的資料已經缺失,找不到了,所以就算你到 Order 資料表中尋找或用其他方法 Join,也不會找到這筆資料。

這個就是 【2. 大的集合中不存在你需要的資料,那麼小的集合也不會有那筆資料】

確定性的資料存在

現在,你收到了一筆資料,告訴你 InstallmentId 大集合與 OrderId 其中某一筆存在:

https://ithelp.ithome.com.tw/upload/images/20210920/20092753rdmKsE8AWP.png

那也可以保證,Installments 這張表一定存在這筆 Order 的連結,這就是 【小的集合存在你需要的資料,那麼大的集合也會有那筆資料】,但反過來說,如果小的集合不存在你需要的資料,不代表大的集合不存在那筆資料。

資料完整性檢查

換一題,你擔心 2017 年某一張 Order 是否缺失所有 Installments 分期付款資訊,所以,檢查 Installments (分期) 的目標是: 是否有任何一筆分期綁到這張指定的訂單,所以你寫了查詢:

SELECT COUNT(*) FROM installments i WHERE i.OrderId = 3 AND YEAR(i.expectInstallAt) = 2017;

這個查詢回傳了結果:

https://ithelp.ithome.com.tw/upload/images/20210920/200927538xqcIPuo0b.png

雖然結果表示這筆訂單是有 1 筆分期資料的,但是無法保證 installments 資料是完整的,這個就表示了,如果你有 2 筆資料,而你目前找到了一筆,就表示了【小的集合 (2017 年的集合) 存在你需要的資料,但不代表所有的集合都找得到另外一筆】。

這篇文章寫的是集合使用的圖表以及解釋邏輯的部分,寫起來頗難臨時創造一個好的例子解釋。

References:
[1] https://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%9B%BE


上一篇
資料表集合與文氏圖
下一篇
物件角色建模 Object Role Modeling
系列文
後端工程師與圖的修練31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言