高性能MySQL之Schema設計對系統性能的影響

 

最近項目接觸數據庫有關設計的內容,平時接觸大數據以及後臺開發偏多,數據庫設計的東西接觸較少,最近打算系統學習下,本文主要是對高性能MySQL書籍中的內容進行一個簡短的總結以及個人理解,記錄一下學習的過程。

 

前言:

與數據庫交互的軟件系統中,系統的架構實現以及數據交互的SQL語句對系統的性能至關重要,系統的數據模型設計實現對系統性能的影響通俗一點說就是數據庫Schema設計對系統的影響。數據庫Schema的設計並不是一件簡單的事情,並不是說做到第三、四範式就算可以了。(個人注:通常大型系統的數據庫Schema設計會通過數據冗餘來提高性能)。不同的數據庫Schema對系統的性能影響各不相同,下面通過一個例子進行說明:

需求概述:一個簡單的討論系統,需要有用戶、用戶組、組討論區這三部分基本功能。

簡單分析:

  1. 需要存放用戶數據
  2. 存放分組信息以及用戶與分組的關係信息
  3. 需要存放討論信息的表

解決方案1:

比較直觀的設計,使用四張表進行存儲,用戶表、分組表、用戶分組關係表以及討論組帖子表,各個表如下:

  1. 用戶表 user

    2. 分組表 groups

3.用戶分組關係表 user_group

 4. 討論帖子表 group_message

 

優化方案2:

1. 用戶表 user

2.用戶畫像表 user_profile

 3.分組表與用戶分組關係表不變

 4.討論組帖子表(注意:此表添加了一個author字段)

5:分組消息內容表

 

方案評估:

憑藉經驗,任何好的設計都是迭代出來的,所謂迭代其實就是在項目的過程中逐漸發現問題,解決問題。馬克思說過:實踐是檢驗真理的唯一標準,數據庫schema設計也不例外,接下來就檢驗一下兩種方案的優劣:

1、場景一

 用戶登陸討論區,選擇一個分組需要將該分組的所有帖子進行分頁顯示,暫時假定一頁顯示20個條目,此時分別對應的SQL如下:

    方案1查詢語句:

SELECT u.id, u.nick_name, t.id, t.subject
FROM USER u, (
		SELECT user_id, subject, id
		FROM GROUP_MESSAGE
		WHERE group_id = '1001'
		ORDER BY gmt_modified
		LIMIT 20
	) t
WHERE t.user_id = u.id;

 

   方案2查詢語句:

SELECT user_id, subject, id, author
FROM GROUP_MESSAGE
WHERE group_id = '1001'
ORDER BY gmt_modified
LIMIT 20

 

結論:很直觀就可以發現,該場景下方案2更優秀,數據庫的join操作往往是導致數據性能差的主要原因,方案2不需要join,一張單獨的表就可以直接查詢出來。該設計就是違背數據庫的範式,但是通過數據冗餘的方式可以提升性能,通過本場景可以知道,讓我們需要避免由於join查詢帶來的性能瓶頸時候可以使用冗餘數據解決,企業中很常見。擔心細心讀者會發現這種設計帶來了暱稱更新需要更新兩張表,對於這個問題一般來說通過程序邏輯控制更新即可,總和來說還是利大於弊,但是實際上很多論壇都是一旦更選擇了用戶名字便不再支持修改名字,這樣就避免了數據不一致的問題。

 

2、場景2

用戶可能時常查詢用戶的信息數據,但是次數相對比較,一般都是用戶在修改個人資料或者點擊其他用戶頭像時候時候纔會查看一個用戶的完整信息,通常情況下只是會顯示用戶的部分信息,我們可以這些必須要顯示的部分用戶信息與部分其他不經常被訪問的用戶信息分爲兩張表存儲,例如方案2設計中的用戶表與用戶畫像表。這麼做對查詢帶來的好處是:可以減少查詢的檢索數據量,提高檢索性能。但是你可能會覺着當要查詢用戶的完整信息時候需要進行用戶表與畫像表的關聯,性能會變差?!性能確實會降低,但是由於用戶表與畫像表都是1對1關聯,關聯字段的過濾性非常高,在根據場景也知道,查詢用戶完整信息發生的頻次也不高,因此此處來帶的損失與場景1中的獲益對比而言,非常微不足道。

 

 

感悟:

      好的代碼一定是重構出來的,好的設計一定是迭代驗證出來的。實踐是檢驗真理的唯一標準。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章