Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Web 第二次新生訓練:系統設計與建模

E91a24de5f8858932171b35bd47c8485?s=47 Rueian
October 11, 2017

Web 第二次新生訓練:系統設計與建模

E91a24de5f8858932171b35bd47c8485?s=128

Rueian

October 11, 2017
Tweet

Transcript

  1. WWW 新生訓練 系統設計與建模 黃瑞安 2017

  2. 在上次確定角色需求與流程狀態分析之後... 在規格達成共識且對規格有足夠信心之後,就可以來考慮資料要怎麼儲存了 一般資料庫規劃建模叫做 Entity-Relationship Modeling 這種建模方式是映射現實業務上實際的需求,不管你決定用哪種資料庫軟體都適用 Entity 與 Relationship: 1.

    Entity 是對應到現實業務需要的物件,例如使用者、場地、申請單 2. Relationship 則是 Enitity 之間的關聯,例如使用者租用場地
  3. 首先要先找出有哪些 Entity 藉由上次的分析,我們可以很輕易地找出關鍵的幾個 Entity 1. 使用者 2. 部門主管 3. 體育室管理員

    4. 申請書 5. 場地 6. 場地租用 7. 信件通知 接下來就開始釐清他們之間的關係
  4. Entity 之間的關係可以分成三類 1. 一對一 2. 一對多 3. 多對多 多對多比較特別,實際上我們會將這個關係轉成中介 Entity

    來儲存,變成一對多與多對一關係:
  5. Fan Traps 通常 E-R Model 關係都是用口語 “動做” 來表示,如上頁的 “manages”, “studies”

    然而口語動作容易有一些誤區,導致做出來的 E-R Model 沒辦法表現一些訊息 例如上圖的 Site 裡面有很多 Despartment,而 Site 雇用很多 Staff 如果關係是這樣子的話,就沒辦法找出一個 Staff 是屬於哪個 Department 可以將關係改成下圖,這樣就可以知道 Staff 是屬於哪個 Department:
  6. Chasm Traps 另外一種情況如上圖:一個 Branch 有很多 Staff,而 Staff 可以看管一些 Property 這裡有個問題是

    Property 不一定會被 Staff 看管,會導致不知道一個 Branch 裡面到 底有哪些 Property,可以將關係改成這樣:
  7. 體育室場地租借 E-R Model 範例

  8. 體育室場地租借 E-R Model 範例 - continue 前一張的申請單的模型還不完整,從規格需求上來說還需要再加上附件、收據、退款 申請這些 Entity

  9. 體育室場地租借 E-R Model 範例 - continue 若我們還需要追蹤申請書狀態轉變的話,則還需要一個 Log Entity,用來記錄發生的 所有事件

    (例如主管審核或是每次與虛擬帳戶檢查付款的紀錄等)
  10. 實際創建資料表 如果你打算採用 Relational Database (如 MySQL) 或是 Document Database (如

    MongoDB) ,其實在 E-R Model 做完之後就可以直接把 Entity 對應到資料庫的 table 或是 collection 了;如果是其他類型的資料庫的話,你會需要自己再做一些轉換來模 擬 table。 在建立資料表的時候,需要考慮一些細節: 1. 表上需要哪些屬性欄位? 2. 哪些資料是冗余欄位?是否要剔除? 3. 會使用到哪些屬性欄位來查詢?如何提升效能? 4. 如何應對未來欄位變動?
  11. 表上需要哪些欄位? 除了業務需要的欄位(如 姓名、電話、建立時間...) 之外,還有一些必要的欄位: 1. 通常每個表都需要 primary key 欄位,常常是一個遞增的 unsigned

    interger primary key 是用來定位表中的每個 row 還有關聯到其他表的 foreign key primary key 欄位上面會有建立 index 與 unique constraint 2. 一張表要關聯到其他表的話(一對一、一對多),會在其中一邊有 foreign key, 用來指向對方的 primary key。 關連式資料庫的 foreign key 身上可以設定 foreign key constraint, 用來確保這個 foreign key 不會指向一個不存在的 primary key
  12. 表上需要哪些欄位?- continue 申請書與審核單的一對多關係

  13. 哪些資料是冗餘欄位,是否剔除? 再定好表上需要哪些欄位屬性之後,可能會發現好像有很多欄位並不需要 假使 B 欄位好像跟 A 重複了,那我們可以考慮幾個問題看是不是可以把 B 移除: 1.

    如果 A 修改了,B 也得跟著一起修改 2. 如果 A 刪除了,B 也得跟著一起刪除 如果上面的條件都符合,那 B 就是冗余的,為了避免修改了 A 而忘了修改 B 的事情 發生,我們可以夠過正規化技巧將 B 移除 其實根據 E-R Model 做出來的表大概都符合第三正規化 不過常常冗余資料移除之後,查詢會變得更困難,效能也會下降,所以要不要移除冗 余也要考慮這些因素來做取捨 若上述條件不符合的話,B 則很有可能是業務所需的必要資料。常見的情況則如訂單 裡面的商品快照,商品快照代表的是下訂單的當下的商品狀態,在下訂單之後不應再 受到上架商品的影響。
  14. 使用者與申請表,申請表上的 user_name、user_phone、user_email、 user_department 欄位是冗余欄位嗎? 哪些資料是冗餘欄位,是否剔除?- continue

  15. 會使用到哪些屬性欄位來查詢?如何提升效能? 在建表的時候,為了要建立好的 index 來提升查詢效能,否則每次都要查詢都要掃過 整張表,需要考慮: 1. 我會用到哪些查詢? 2. 資料庫是怎麼取出我要的資料? 例如:要查詢某個時段的場地的所有借用的

    SQL: SELECT * FROM reservations WHERE field_id = x AND state = occupied AND start_at >= xxx AND start_at <= yyy 對應的 index 則是 field_id_state_start_at 或是 state_field_id_start_at
  16. 會使用到哪些屬性欄位來查詢?如何提升效能? 為什麼是用 field_id_state_start_at 或 state_field_id_start_at 呢? index 的結構是多層的,以 field_id_state_start_at 為例的話,這個

    index 就有三層 1. 第一層是對整張表的 field_id 排序 2. 第二層是每個 field_id 底下再對它有的 state 排序 3. 第三層是每個 field_id 底下的每個 state 底下再對它有的 start_at 排序 所以上頁的 SQL 如何應用這個 index 找到符合條件的資料? 1. 在第一層中尋找指定的 field_id,進到第二層 2. 在第二層中尋找指定的 state,進到第三層 3. 在第三層中尋找符合範圍的 start_at,得出符合條件的 rows 從這邊也可以看出 field_id 跟 state 是可以調換順序不影響效能的。至於到底誰要放 前面,則可以考慮是不是有其他的查詢也可以共用這個 index。 試想如果把 start_at 放在最前面的話,上頁的 SQL 會怎麼使用這個 index 呢?
  17. 如何應對未來欄位變動? 儘管現在定好了規格,還是很有可能在系統上線之後因為各種原因會需要調整流程 跟規格,常常連帶資料表都會需要修改。這種時候要特別需要注意線上的資料要怎麼 調整,例如借用流程需要修改,但已經有一堆申請單正在審核。 情況可分四種: 1. 流程沒有調整,完全不影響舊資料 (可能只是加個欄位) 2. 流程有調整,在相關的表都加上版本欄位,用來區分流程的業務邏輯

    3. 流程有調整,重新建立新流程的相關表與業務邏輯,舊的都保持不動,重疊的部 分則用版本欄位區分 4. 流程有調整,重新建立新流程的相關表與業務邏輯,將舊的資料全部轉移到新的 流程。
  18. 體育室場地借用系統資料表範例 (不包含體育室管理員與部門主管)

  19. 還有一些小細節 1. 如果服務不能中斷,要怎麼安全的進行 Database migration? 2. 如何使用 RDBMS 的 Transaction

    ? 3. … 留到下次新生訓練囉,下次會繼續講 Laravel 的功能與部分邏輯實作~