畫出關係
另有 28 種語言版本
English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

第 2 個模組,共 6 個,屬於 Data Architect 課程第 2 章為含義建模資料。每個模組都可以單獨閱讀。 上一篇:聆聽名詞 · 下一篇:構建邏輯模型
**本模組回答的問題:**如何把候選實體變成一個概念資料模型?
名詞已經上了白板。現在我想了解的是方框之間的連線,因為一堆實體還不算真正的資料模型。很多含義就存在於關係之中。一個零售合作夥伴運營著若干配送中心。一份裝貨清單列出若干配送。一次配送送達一位收貨人。一個配送小組駕駛一輛卡車。每一句陳述都告訴我關於業務的一些東西,每一句也都給了我另一個要問的問題。
從業務語言開始
Section titled “從業務語言開始 ”我仍然不想談 Salesforce。我不是在問這應該是查閱關係還是主要-詳細資料關係,不是在考慮 Salesforce 交叉物件(Junction Object),也不是在決定父記錄被刪除時會發生什麼。我是在努力理解業務上的關係。
拿**「一個零售合作夥伴運營著若干配送中心」**來說。聽起來很簡單。但一個零售合作夥伴有一個配送中心還是多個?在 Steve Trucking,每個零售合作夥伴在 Steve Trucking 服務的每個區域都運營著一個區域配送中心,所以是多個。一個配送中心可以屬於多個零售合作夥伴嗎?配送中心本身是否重要,有自己的員工和歷史,還是隻是一個地址?如果某個零售合作夥伴離開了,我們還在意它的配送中心嗎?
這些不是 Salesforce 問題,而是業務問題,而答案可能徹底改變模型。
在深入之前,我想先給你一套從現在起每張圖都會用到的語言。它很小。兩個方框之間的一條線表示這兩樣東西相關,線兩端的標記表示有多少。
從一條普通的線開始,沒有任何標記。這是我在白板上的起點:我知道這兩個名詞相關,只是還沒問怎麼相關。然後線的兩端加上標記。橫穿線條的一道短豎線,也就是那個十字,表示一。鴉爪,也就是像鳥爪一樣分成三叉的那一端,表示多。在本模組後面,你會看到第一個標記旁邊出現第二個標記,一道豎線或一個圓圈,它回答的是另一個問題:可以沒有嗎?
要記住的唯一規則:**每個標記都在它所接觸的方框那一端來讀。**離方框最近的標記表示最多可以有多少;往外的下一個標記表示最少有多少。
坐下、別動、建模
Section titled “坐下、別動、建模 ”在講 Steve Trucking 之前,先回到模組 1 裡的狗。我們有五個方框:主人、繁育者、狗、品種和技能。現在我要問它們之間的連線。
**一個還是多個?**一位主人可以有不止一隻狗;Ana 就有兩隻。一隻狗只有一位主人,至少在我們的模型裡是這樣。這就是一對多:主人一端畫一道豎線,狗一端畫鴉爪。繁育者也是同樣的形狀:一個繁育者繁育很多隻狗。
**可以沒有嗎?**Max 來自收容所,所以他根本沒有繁育者。繁育者一端加一個圓圈:一隻狗有零個或一個繁育者。不過每隻狗都有主人,所以那一端再加一道豎線:恰好一個。
**多對多?**一隻狗會很多項技能,而一項技能,比如坐下,有很多隻狗會。這就是多對多,而這正是我去尋找隱藏概念的地方。關於這隻狗會這項技能,有沒有什麼要說的?她做得有多好,什麼時候學會的。這個關係有它自己的事實,所以它成了一個獨立的事物:狗狗技能(Dog Trick),狗的名字放在前面,因為驅動它的是狗。
**每條線是什麼意思?**主人擁有一隻狗。繁育者繁育它。一隻狗會它的技能。給連線起好名字,任何人都能把模型讀回給你聽。
現在,還是隨時間變化?有沒有人在意 Bella 今天坐下做得有多好,或者她是怎麼練到這一步的?如果訓練師每隔幾個月檢查她一次,每次檢查就是一條獨立的記錄:一條技能評估(Trick Assessment),帶有日期、熟練程度和檢查人,歸屬於它所屬的那條狗狗技能。即使是一個已經變成事物的關係,也可以有它自己的歷史。
品種我暫時不連線。它仍然是模組 1 留下的那個問題:是一個獨立的方框,還是狗身上的一個詞,模組 4 會解決它。
這些問題中的每一個,放到真實的業務上都同樣適用。現在我們拿它們來問 Steve Trucking。
問「一個還是多個?」
Section titled “問「一個還是多個?」 ”關於一個關係,我最先想了解的事情之一是它的基數。這是資料庫術語;問題本身要簡單得多:**這邊的多少個可以與那邊的多少個相關?**在概念層次上,有三種基本模式。
這是整個過程中重要的一步:拿兩個不同的名詞,理解它們之間的關係。在大多數情況下,它是一對多或多對一。只有在少數情況下,你才會碰到一對一。
一對多無處不在。一個零售合作夥伴有多個配送中心。一份裝貨清單列出多次配送。一條路線有大約十個停靠點。聽到這樣的話,我就開始畫線。
現在這條線有了標記。每一端都說明它所接觸的方框有多少:豎線表示一,鴉爪表示多。從每個方框出發去讀:一個零售合作夥伴有多個配送中心。
一對一關係是存在的,但很少見,一旦發現,我會問一些問題。這真的是兩個不同的名詞,還是同一個?如果是不同的,它們之間的一對一關係是什麼?它會永遠是一對一,還是隻是現在一對一?這些都是設計資料模型時的關鍵問題。在任何一個早上,配送小組和卡車看起來都是一對一的:兩個人,一輛卡車,一條路線。但放到一個月裡看就不是了,而這個模型裡最有意思的關係正藏在那裡。
多對多關係特別有意思,因為它們常常告訴我們業務中還有另一個概念。一個配送小組會在一段時間裡開不止一輛卡車嗎?會。一輛卡車會由不止一個配送小組駕駛嗎?在它的整個使用期內,當然會。所以配送小組和卡車是多對多關係。但現在我想了解更多。業務方是否在意某個配送小組什麼時候開過某輛卡車?為哪條路線,在哪一天?是誰做的分配?如果關係本身承載著我們在意的資訊,我們就發現了另一個業務概念:配送小組分配(Crew Assignment)。
這是一個重要的建模習慣。有時最有意思的東西並不是我們最初聽到的某個名詞,而是藏在兩個名詞之間的關係裡。
關係可以變成事物
Section titled “關係可以變成事物 ”這是我希望管理員開始換個角度思考的地方之一。在 Salesforce 裡,我們習慣談論物件和欄位,所以很容易把方框當成重要的部分,把連線當成管道。但關係本身可以有業務含義。
想想一次配送和它所載的產品。一次配送可以載好幾種產品,比如一臺洗衣機和一臺烘乾機。一種產品,比如同一型號的冰箱,會出現在成千上萬次配送中。這很簡單。但如果我需要知道這次配送裡有幾臺這種產品、是否要安裝、是否要把舊的拉走呢?我感興趣的就不再只是配送和產品之間的關係了。我感興趣的是一個配送項目(Delivery Item),而這個概念值得擁有自己的實體。
如果你有 Salesforce 背景,你可能已經在想:「這是個交叉物件。」你沒錯。但我不想從那裡開始。**配送項目先是一個業務概念,然後才是一個 Salesforce 交叉物件。**業務在先,實現在後。
對於這類關係實體,不管最後在哪裡構建,我都有幾個習慣。
給它起名字。如果業務方已經有一個詞,就用他們的。如果沒有,就把兩個父實體的名字拼在一起。想想訂單和產品。它們之間的東西是 Order Item(訂單項目):訂單,以及訂單上的項目。它同時是兩個父實體的子實體,在 Salesforce 裡最後可能成為一個 Salesforce 交叉物件。但哪個名字放在前面:Item Order,還是 Order Item?看看每個父實體是哪類資料。產品是參考資料;訂單是交易資料,而驅動它的是訂單。所以是 Order Item,或者 Order Product,就像 Salesforce 有 Opportunity Product(商機產品)一樣。在 Steve Trucking,它是配送項目(Delivery Item)。起驅動作用的名字放在前面,這樣在你將來看到的每一個清單裡,這條記錄都會排在它的所有者旁邊。
**給它自己的鍵。**人們很容易說配送項目由配送加產品來識別,然後就此打住。那是一個複合鍵,而複合鍵要難處理得多:每個指向這條記錄的系統都得帶著兩半。給關係實體一個自己的識別符號,把配送加產品作為一條關於唯一性的規則,而不是作為身分。
注意它上面沒有什麼:序列號。數量和序列號不屬於同一條記錄。數量統計的是某樣東西的若干件;序列號識別的是某一件特定的東西。如果業務需要序列號,每一件就成為自己的一條記錄,五臺冰箱就是五條記錄。我想不出有什麼理由讓配送項目下面再掛一個配送項目明細。要麼是這個,要麼是那個:帶數量的彙總,或者每件一條記錄。這裡用的是數量。
**留意想要歷史的屬性。**有些關係實體一旦建立就定下來了:這次配送裡的洗衣機,就一直是這次配送裡的洗衣機。另一些則不斷變化。一個配送小組這週開 117 號卡車,下週這輛卡車就歸了另一個小組。當關系會變化,而業務又在意它過去是什麼樣時,這個關係實體就需要日期,而配送小組分配正是需要留意的那一個。儘早問業務方在意的是現在還是隨時間變化;我們馬上會回到這個話題。
關係的含義不止於基數
Section titled “關係的含義不止於基數 ”光說「一對多」不足以理解一個關係。我還想知道這個關係意味著什麼。
一次配送有一個地點。哪一個?它出發的配送中心?還是它送達的收貨人家裡?這兩者不能互換。兩個模型可以有完全相同的方框和完全相同的基數,而連線卻可以意味著完全不同的東西。這就是為什麼好的模型不只是用線連起來的方框。**連線需要名字。**如果我把圖交給另一位架構師,他們不應該需要去猜一個關係是什麼意思;如果我拿給業務方看,它應該使用他們認得的語言。
可選性同樣重要
Section titled “可選性同樣重要 ”「有多少?」裡還藏著另一個問題:這個關係是必需的嗎?一次配送能在被排上路線之前存在嗎?必須能:裝貨清單在配送前一兩天到達,而路線要到前一天晚上才最終確定。一次配送能在沒有零售合作夥伴的情況下存在嗎?不能;每一次配送都來自某個合作夥伴的裝貨清單。這就是可選性。
同樣,不要直接跳到 Salesforce 的必填核取方塊。說「每次配送都必須有一個零售合作夥伴」和說「Salesforce 應該在建立記錄時要求填寫零售合作夥伴欄位」是有區別的。它們最後可能是同一種實現,但不是同一句話。前者是一條業務規則;後者是執行它的一種方式。作為架構師,我們要先理解前者,再決定後者。
在圖上,可選性是每一端的第二個標記。離方框最近的標記表示最多可以有多少:豎線表示一,鴉爪表示多。往外的下一個標記表示最少有多少:又一道豎線表示至少一個,一個圓圈表示可以是零。所以每次配送都恰好在一份裝貨清單上,而一份裝貨清單列出一次或多次配送。一次配送位於零個或一個停靠點,在排上路線之前沒有停靠點,而一個停靠點卸下零次或多次配送。
時間會改變關係
Section titled “時間會改變關係 ”有一個問題我經常問:你說的是現在,還是隨時間變化?
一個配送小組駕駛一輛卡車。是現在嗎?是為了今天的路線嗎?還是在這兩個人共事的整個期間?這會產生不同的模型。如果業務方只在意一個小組今天開的是哪輛卡車,模型可以保持簡單。如果需要知道一個小組開過的每一輛卡車、什麼時候、在哪條路線上,我們就需要歷史,而我們發現的那個配送小組分配突然就變得非常重要了。
這是建模錯誤的一個常見來源。我們為當前狀態建模,因為那是我們在螢幕上能看到的。然後,幾週後,某個零售合作夥伴提出一起貨損索賠,有人問:「3 月 17 日是哪個小組開的 117 號卡車?」於是我們發現,每次分配變化時,我們都把答案覆蓋掉了。
保留這種歷史的一種方法,是讓分配成為一條獨立的記錄。給某個小組分配時,我們建立一條帶開始日期的配送小組分配。分配變化時,我們給舊記錄加上結束日期,再建立一條帶自己開始日期的新記錄。現在,「六個月前是誰負責那項分配?」就成了一個簡單的問題,而不需要去翻欄位歷史記錄或資料變更日誌。而一旦某個小組有過很多次分配,就會有人問哪一次是當前的,所以我還會加一個 Active(有效)標誌。
所以,當有人告訴我一個關係時,我不只問這些東西如何相關。我會問:這個關係會變化嗎?我們在意它的歷史嗎?
先畫圖,再配置
Section titled “先畫圖,再配置 ”我們的 Steve Trucking 模型正在變得有用。我們知道哪些關係是一對多,多對多關係在哪裡藏著另一個概念,哪些關係是可選的,哪些會隨時間變化。而我們仍然沒有建立任何 Salesforce 物件。這是有意的。
這張圖應該是我可以擺到業務方面前的東西,而且他們不需要了解 Salesforce 就能告訴我它對不對。如果因為圖裡滿是 Salesforce 術語而導致他們無法驗證,那我就過快地進入物理設計了。
架構師在這裡決定什麼
Section titled “架構師在這裡決定什麼 ”在梳理概念模型中的關係時,我要決定的是:
- 主要的業務實體彼此如何關聯。
- 每個關係現在以及隨時間變化後,是一對一、一對多還是多對多。
- 每個關係是必需的還是可選的。
- 某個多對多關係是否藏著一個有意義的業務概念。
- 關係是否隨時間變化,以及我們是否需要它的歷史。
查閱關係還是主要-詳細資料關係、交叉物件的配置、級聯行為和共用,這些都是物理層面的決定;我們會講到。現在我們仍在回答那個更重要的問題:這個業務實際上是如何運作的?一旦理解了實體以及它們之間的關係,我們就可以開始新增描述它們的細節。那時,我們的概念模型就開始變成一個邏輯資料模型了。
