數據庫設計(Database Design)是指對於一個給定的應用環境,構造最優的數據庫模式,創建數據庫及其應用系統,使之可以有效地存儲數據,知足各類用戶的應用需求(信息要求和處理要求)。在數據庫領域內,經常把使用數據庫的各種系通通稱爲數據庫應用系統。 數據庫設計的設計內容包括:需求分析、概念結構設計、邏輯結構設計、物理結構設計、數據庫的實施和數據庫的運行和維護。git
◆ 課程的屬性:{主標題,副標題,方向,分類,難度最新最熱,時長,簡介,人數,需知,收穫,講師名講師職位,課程圖片綜合評分,內容實用,簡潔易懂,邏輯清晰}github
◆ 課程列表的屬性:{章名,小節名, 說明,小節時長,章節URL,視頻格式}數據庫
◆ 講師的屬性:{講師暱稱,說明,性別,省,市,職位說明,經驗,積分,關注人數,粉絲人數}bash
◆ 問答評論屬性:{類型,標題,內容,關聯章節,瀏覽量,發佈時間,用戶暱稱}數據庫設計
◆ 筆記的屬性:{用戶暱稱,關聯章節 筆記標題,筆記內容,發佈時間}。函數
◆ 用戶的屬性:{用戶暱稱密碼,說明,性別,省,市,職位,說明,經驗,積分,關注人數粉絲人數}性能
◆評價的屬性:{用戶,課程主標題,內容,綜合評分,內容實用,簡潔易懂,邏輯清晰,發佈時間}學習
◆ 課程的屬性:{主標題,副標題,方向,分類難度最新,最熱,時長,簡介,人數,需知,收穫,講師名,講師職位,課程圖片綜合評分,內容實用,簡潔易懂,邏輯清晰}測試
例如當使用 優化
例如,咱們想新增Java開發方向的課程
例如,咱們想刪除數據庫方向
咱們只是單純想刪除數據庫方向而已,但該語句卻將許多課程也刪除了,這並不符合咱們的預期.
相同的數據在一個表中出現了屢次
那麼是否是這麼多問題就意味着寬表一無可取呢?存在即合理!
因爲寬表中,全部數據存在於一個表中,所以在查詢時,無需多表查詢,SQL執行效率較高,且存在的上述問題在報表應用中都不是大問題
既然寬表不適合咱們的當前業務,那麼怎麼尋找合適的方法呢?
例如如下實例中的聯繫方式是一個複合屬性,明顯就違反了該範式,在數據庫中是沒法分離出來的
咱們只需對其進行簡單的改動便可
即標準的二維表.
前提
標準的二維表,即第一範式成立
表中必須存在業務主鍵,而且非主鍵依賴於所有
業務主鍵
例如以下博客表實例
使用用戶字段做爲PK是否可行呢? 顯然一個用戶會對應多個博客記錄,且章節標題也能爲多個用戶編輯,因此單列字段PK失效
使用<用戶,章節,標題>的複合PK 然而用戶積分字段也只和用戶字段依賴,並不依賴於總體的PK,因此依舊不符合第二範式
拆分將依賴的字段單獨成表
從上面,咱們也能夠發現:
依舊看看課程表
首先,一個字段的PK顯然符合第二範式,大部分字段也只依賴於PK,然而對於講師職稱字段實際上是依賴於講師名的,因此不符合第三範式.
{主標題,副標題,方向,分類,難度,最新,最熱,時長,簡介,人數,需知,收穫,講師名講師職位,課程圖片綜合評分,內容實用,簡潔易懂,邏輯清晰}
咱們顯然能夠將其拆分以下:
主標題(PK)
,副標題,方向,分類,難度,上線時間,學習人數,時長,簡介,需知,收穫,講師暱稱,課程圖片,綜合評分,內容實用,簡潔易懂,邏輯清晰
講師名及講師的職稱
其中最新
屬性即對應着上線時間計算得出,業務上可規定時間段判斷是否爲最新 最熱
屬性便可以學習人數字段排序來反映
課程方向名稱(PK)
: 在課程表中有對應的方向字段 添加時間
分類名稱(PK)
: 在課程表中有對應的方向字段 添加時間
課程難度(PK)
: 在課程表中有對應的方向字段 添加時間
[章節名,小節名](聯合PK)
說明,小節時長,章節URL,視頻格式
其中,說明
其實只依賴於章節名
小節時長
,小節URL
,視頻格式
都只依賴於小節名
違反第二範式,因此須要拆分字段
章節名(PK)
,說明,章節編號
主標題,章節名
小節名稱(PK),小節視頻url,視頻格式,小節時長,小節編號
主標題,章節名,小節名
講師名,密碼,性別,省,市,職稱,說明,經驗,積分,關注數,粉絲數
講師名(PK)
,密碼,性別,省,市,職稱,說明,經驗,積分,關注數,粉絲數
用戶暱稱,密碼,性別,省市,職位,說明,經驗,積分,關注數,粉絲數
用戶暱稱(PK)
,密碼,性別,省市,職位,說明,經驗,積分,關注數,粉絲數
和講師表基本相同,且講師其實也是一種用戶,講師的信息就會被存儲兩次,形成數據的冗餘.,因而就難以保持數據一致性!考慮合併!
用戶暱稱(PK)
,密碼,性別,省市,職位,說明,經驗,積分,關注數,粉絲數,講師標識
類型,標題,內容關聯章節,瀏覽量,發佈時間,用戶暱稱
其中標題文字是共享的,沒法保持一致 同一用戶在不一樣章節提出的問題也可能相同 所以決定採用標題+用戶暱稱+關聯章節
做爲PK
如何記錄關聯章節字段呢? 是否是隻能用課程章節的PK來記錄呢? 所以,不得不將課程章節的關聯表PK加入
[標題,課程主標題,課程章名,小節名稱,用戶呢稱](PK)
父評論(被回覆的問題/標題) 標題,內容,類型,瀏覽量,發佈時間
用戶暱稱,關聯章節,筆記標題,筆記內容,發佈時間
和評論實體差很少,分析再也不贅述
[筆記標題,課程主標題,課程章名,小節名稱,用戶呢稱](PK)
內容,發佈時間
用戶呢稱;課程主標題,內容,綜合評分,內容實用,簡潔易懂,邏輯清晰,發佈時間
[用戶呢稱;課程主標題](PK)
內容,綜合評分,內容實用,簡潔易懂,邏輯清晰,發佈時間
只有選擇/購買了課程的用戶才能評價!!! 須要用戶與所選課程的關聯關係表
[用戶呢稱;課程主標題](PK)
選課時間,累積聽課時長
若是咱們想要查詢出一門課程包括全部章節和小節的相關信息
咱們就要關聯5個表,查詢效率極低!且查詢課程信息的需求很大! 爲了提升性能,咱們還須要對錶結構進行優化操做
空間換時間的思想
因此能夠並不須要關聯關係表,而是呢能夠直接把課程表和課程&章節聯繫表合併
課程章節表
[主標題,章節名](PK)
,說明,章節編號
雖然違反了第二範式,可是減小了一個表的查詢,提升了查詢性能,在頻繁查詢操做的系統中,這很值得!
通過反範式化後,咱們只須要查詢三個表便可
課程相關表數量 5 -> 3
經過數據冗餘避免數據不一致
課程章節表:{章節ID(PK),課程ID,章節名稱,章節說明,章節編號}
課程小節表:{小節ID(PK),課程ID,章節ID,小節名稱,小節視頻url,視頻格式,小節時長,小節編號}。
課程方向表:{課程方向ID(PK),課程方向名稱,填加時間}
課程分類表:{課程分類ID(PK),分類名稱,填加時間}
課程難度表:{課程難度ID(PK) ,課程難度,填加時間}
用戶表:{用戶ID(PK),用戶暱稱,密碼,性別,省市,職位,說明,經驗,積分,關注 人數,粉絲人數,講師標識}
問答評論表:{評論ID(PK),父評論ID ,課程ID,章節ID,小節ID ,評論標題,用戶 ID,內容,類型,瀏覽量,發佈時間}
筆記表:{筆記ID(PK),課程ID,章節ID,小節ID筆記標題,用戶呢稱,筆記內容, 發佈時間}
評價表:{評價ID(PK),用戶ID,課程ID,內容綜合評分,內容實用,簡潔易懂,邏 輯清晰,發佈時間}
用戶選課表:{用戶選課ID(PK),用戶ID,課程ID,選課時間,累積聽課時長}
新建表
插入數據
查詢結果
因爲北京時間是東八區,所以咱們更改時區
新的查詢結果
這就是timestamp具備時區性的特色
INET_ATON( '255.255.255.255' ) = 4294967295
INET_ NTOA(4294967295) ='255.255.255.255'
複製代碼
數據遷移的時候,它幾乎不可能被其餘數據庫所支持,若是 ENUM 裏面是字符串,對於其餘數據庫來講就更鬱悶了,還不能設爲tinyint等類型的字段
純數字類型的不建議用枚舉類型,這是由於在 ENUM 內部維護有一個隱形的索引,也是按數字排列的,容易混淆;添加枚舉值也是一個問題,若是添加在最後還好,若是添加在中間什麼位置的話,原來的隱藏索引將再也不起做用
ENUM 字段默認是能夠插入 NULL 值的,這個就比較尷尬了,並且沒有辦法優化
若是插入的值比ENUM設定的值大,會默認保存成接近的那個值;插入的值不能包含函數,不能傳遞參數
因此若是插入的值是數字型的,建議用tinyint,若是插入的值是字符型的,建議用char。若是真想用 ENUM 也是能夠得,前提是要了解到 ENUM 的弊端,就能夠有效規避這些問題
一、前奏:【業務分析】欲善其事,必三思而行; 二、高潮:【邏輯設計】範式化VS反範式化; 三、結束:【物理設計】存儲引擎&數據類型&命名規約。
更多內容請關注JavaEdge公衆號