如何做好表結構設計?
前言
最近有不少前端和測試轉Go的朋友在??交流群??里聊:如何做表結構設計?
大家關心的問題陽哥必須整理出來,希望對大家有幫助。
4個方面
設計數據庫表結構需要考慮到以下4個方面:
- 數據庫范式:通常情況下,我們希望表的數據符合某種范式,這可以保證數據的完整性和一致性。例如,第一范式要求表的每個屬性都是原子性的,第二范式要求每個非主鍵屬性完全依賴于主鍵,第三范式要求每個非主鍵屬性不依賴于其他非主鍵屬性。
- 實體關系模型(ER模型):我們需要先根據實際情況畫出實體關系模型,然后再將其轉化為數據庫表結構。實體關系模型通常包括實體、屬性、關系等要素,我們需要將它們轉化為表的形式。
- 數據庫性能:我們需要考慮到數據庫的性能問題,包括表的大小、索引的使用、查詢語句的優化等。
- 數據庫安全:我們需要考慮到數據庫的安全問題,包括表的權限、用戶角色的設置等。
設計原則
在設計數據庫表結構時,可以參考以下幾個優雅的設計原則:
- 簡單明了:表結構應該簡單明了,避免過度復雜化。
- 一致性:表結構應該保持一致性,例如命名規范、數據類型等。
- 規范化:盡可能將表規范化,避免數據冗余和不一致性。
- 性能:表結構應該考慮到性能問題,例如使用適當的索引、避免全表掃描等。
- 安全:表結構應該考慮到安全問題,例如合理設置權限、避免SQL注入等。
- 擴展性:表結構應該具有一定的擴展性,例如預留字段、可擴展的關系等。
最后,需要提醒的是,優雅的數據庫表結構需要在實踐中不斷迭代和優化,不斷滿足實際需求和新的挑戰。
下面舉個示例讓大家更好的理解如何設計表結構,如何引入內存,有哪些優化思路:
問題描述
如上圖所示,紅框中的視頻篩選標簽,應該怎么設計數據庫表結構?
這是一個很好的應用場景,大家可以先自己想一下。不要著急看我的方案。
需求分析
- 可以根據紅框的標簽篩選視頻
- 其中綜合標簽比較特殊,和類型、地區、年份、演員等不一樣
- 綜合是根據業務邏輯取值,并不需要入庫
- 類型、地區、年份、演員等需要入庫
- 設計表結構時要考慮到:
- 方便獲取標簽信息,方便把標簽信息緩存處理
- 方便根據標簽篩選視頻,方便我們寫后續的業務邏輯
設計思路
- 綜合標簽可以寫到配置文件中(或者寫在前端),這些信息不需要靈活配置,所以不需要保存到數據庫中
- 類型、地區、年份、演員都設計單獨的表
- 視頻表中設計標簽表的外鍵,方便視頻列表篩選取值
- 標簽信息寫入緩存,提高接口響應速度
- 類型、地區、年份、演員表也要支持對數據排序,方便后期管理維護
表結構設計
視頻表
字段 | 注釋 |
id | 視頻主鍵id |
type_id | 類型表外鍵id |
area_id | 地區表外鍵id |
year_id | 年份外鍵id |
actor_id | 演員外鍵id |
其他和視頻直接相關的字段(比如名稱)我就省略不寫了
類型表
字段 | 注釋 |
id | 類型主鍵id |
name | 類型名稱 |
sort | 排序字段 |
地區表
字段 | 注釋 |
id | 類型主鍵id |
name | 類型名稱 |
sort | 排序字段 |
年份表
字段 | 注釋 |
id | 類型主鍵id |
name | 類型名稱 |
要么是年份正序排列,要么是年份倒序排列,所以不需要sort字段
演員表
字段 | 注釋 |
id | 類型主鍵id |
name | 類型名稱 |
sort | 排序字段 |
表結構設計完了,別忘了緩存
緩存策略
首先這些不會頻繁更新的篩選條件建議使用緩存:
- 比較常用的就是redis緩存
- 再進階一點,如果你使用docker,可以把這些配置信息寫入docker容器所在物理機的內存中,而不用請求其他節點的redis,進一步降低網絡傳輸帶來的耗時損耗
- 篩選條件這類配置信息,客戶端和服務端可以約定一個更新緩存的機制,客戶端直接緩存配置信息,進一步提高性能
列表數據自動緩存
目前很多框架都是支持自動緩存處理的,比如goframe和go-zero,官方文檔都做了詳細的介紹,不作為本文的重點。
goframe
可以使用ORM鏈式操作-查詢緩存[1]
官方示例:
go-zero
DB緩存機制[2]
go-zero緩存設計之持久層緩存[3]
官方文檔都做了詳細的介紹,不作為本文的重點。
總結
這篇文章介紹了設計數據庫表結構應該考慮的4個方面,還有優雅設計的6個原則,舉了一個例子分享了我的設計思路,為了提高性能我們也要從多方面考慮緩存問題。
本文拋磚引玉,歡迎大家留言交流。
相關資料
[1]ORM鏈式操作-查詢緩存: https://goframe.org/pages/viewpage.action?pageId=1114346
[2]DB緩存機制: https://go-zero.dev/cn/docs/blog/cache/cache
[3]go-zero緩存設計之持久層緩存: https://go-zero.dev/cn/docs/blog/cache/redis-cache
本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。
轉載本文請聯系「 程序員升級打怪之旅」公眾號。