2012-11-01 65 views
0

我正在開發一個最終將擁有數百萬用戶的系統。系統的每個用戶都可以訪問系統中不同的「選項卡」。我正在用一個名爲usertabs的表跟蹤這個問題。有兩種方法可以處理這個問題。簡單記錄的Mysql優化 - 什麼是最好的?

方式1:包含用戶標識和tab1-tab10作爲int列的每個用戶的單行。

該系統的優點是,通過用戶ID獲得單行的查詢速度非常快,而缺點是「空」列佔用空間。另一個缺點是,當我需要添加一個新選項卡時,如果有數百萬條記錄,我將不得不重新組織整個表。但是這不會經常發生。

方式2:單行包含userid和tabid,這就是全部。每個用戶最多可以有10行。

該系統的優點是容易分片或其他機制優化存儲和沒有浪費的空間。行僅在必要時才存在。缺點是每次訪問記錄時必須讀取10行。如果這些行是分散的,它們可能會更慢或更快,這取決於它們的存儲方式。

我的程序員側朝路1傾斜,而我的大數據側朝路2

,你會選擇哪傾斜?爲什麼?

回答

2

過早的優化,和所有...

選擇1看似「容易」,但你已經確定的主要缺點 - 可擴展性是一個巨大的痛苦。

我也確實懷疑它會比選項2更快 - 數據庫非常專門設計用於查找相關位數據,並且找到10條記錄而不是1條記錄幾乎肯定不會影響您的測量。

「Scattered」記錄並不重要,數據庫使用索引能夠非常快速地檢索數據,而不管它們的物理位置如何。

這當然取決於對外鍵使用索引,如@Barmar註釋。

+0

推論:確保您爲所有加入的字段創建索引。 – Barmar

+0

謝謝內維爾。我正在這樣傾斜。只是想知道其他人是否有不同的意見。 '便利。方式2可以通過模型本身的方式2輕鬆克服,使'使用'代碼完全相同。 (在控制器的頂層等)。 –

1

如果這些行分散,它們可能會更慢訪問或可能更快,這取決於它們的存儲方式?

如果您正確使用clustering,它們不必分散。

InnoDB tables are always clustered,如果你的子表的PK 類似於:{user_id, tab_id} ,這將自動存儲屬於同一用戶的標籤身體緊貼在一起,查詢「中給予用戶的選項卡中減少I/O 」。

OTOH,如果您的小孩PK是:{tab_id, user_id},這會將連接到同一個標籤的用戶物理上靠近在一起,從而使查詢如「讓所有用戶連接到指定標籤」的查詢速度非常快。

不幸的是,MySQL不支持前沿索引壓縮(a-la Oracle),因此您仍然需要爲重複所有這些user_id(或第二種情況下的tab_id s)支付存儲(和緩存)在子表中,但儘管如此,我仍然會尋求解決方案(2)以獲得靈活性和(可能)查詢的簡便性。


其中的InnoDB自動使用聚類關鍵。

即,用戶的PK位於子表PK的前沿。

+0

謝謝。我確實有一個userid,tabid組合作爲獨特的PK。 –

相關問題