2013-04-27 39 views
4

在我正在處理的項目上,我們有一個活動表,每個活動可以鏈接到大約20個不同的「活動詳細信息」表中的一個...使用大量可能的連接進行查詢的最佳方法

eg如果活動是「工作」類型,那麼它將具有相應的activity_details_ 工作記錄,如果它是「病假」類型,那麼它將具有相應的活動記錄_ 病假記錄等。

當前我們正在加載活動,然後對於每個活動我們都有一個單獨的查詢來從相關表中獲取活動詳細信息。如果你有成千上萬的活動,這顯然不能很好地擴展。

所以,我最初的想法是有一個單一的查詢,它提取活動並一次加入細節。

SELECT * FROM activity 
LEFT JOIN activity_details_1_work ON ... 
LEFT JOIN activity_details_2_sickleave ON ... 
LEFT JOIN activity_details_3_travelwork ON ... 
...etc... 
LEFT JOIN activity_details_20_yearleave ON ... 

但是,這將導致每個記錄有100個字段,其中大多數是空的,並且感覺討厭。

延遲加載細節不是一個真正的選擇,因爲細節幾乎總是在覈心邏輯中被請求,至少對於主要類型來說。

有沒有這樣做的超級聰明的方式,我沒有想到?

預先感謝

+2

您是否需要查詢任何連接表的屬性?你的RDBMS和「託管」環境是什麼? (有關於RDBMS的具體解決方案)。 – dasblinkenlight 2013-04-27 13:09:58

+0

@dasblinkenlight不,我不需要查詢細節,它主要是信息性的東西。我們使用MySQL並使用mysqli連接到它,然後僅使用一小段代碼將數據記錄映射到相關的類,例如Activity,ActivityDetailsAbsence等 – MeatPopsicle 2013-04-27 13:43:29

+0

根據表的大小,這個查詢會非常沉重。生成活動饋送是NoSQL所做的非常好的事情。可能想看看redis/mongo如何適合這種用例? – super9 2013-04-27 14:14:13

回答

2

我的建議是定義視圖的每個ActivityType,即具體地,涉及活動定製。

然後通過ActivityType字段在Activity表上添加一個索引。集羣表示索引,除非有其他需要集羣的需求(或者性能基準測試顯示某些其他集羣選擇更高性能)。

是否有一個特定的原因,爲什麼這種非規範化程度的設計?這是衆所周知的原因嗎?

+0

我不確定這樣做的確切原因,但詳細信息表上確實有大量字段,例如,activity_details_work表有20多個信息字段,您認爲如果所有細節最初存儲在活動表中呢? – MeatPopsicle 2013-04-28 09:36:31

+0

@MeatPopsicle:並非20+個字段先於許多字段,而是捕獲了關於數據的如此小的元知識。但只有一個傻瓜在理解最初的動機之前就急於改變。 – 2013-04-28 13:06:17

2

你的活動表有可能是(date_from, date_to, with_who, descr)或者其他的東西。正如Pieter建議的那樣,考慮拋出類型varchar或enum字段,以處理單個細節表。

如果有合理的理由來保持桌分開,考慮添加保持布爾/ TINYINT字段(has_workhas_sickleave等),或位串(has_activites_of_type,其中第一位置達has_work觸發器,旁邊has_sickleave等)。

無論採用哪種方法,您都可以通過在一個或多個單獨的查詢中獲取活動的詳細信息來獲得更好的效果 - 如果只是爲了避免字段名稱衝突。

1

我不認爲enum是要走的路,因爲正如你所說可能有1000個活動,那麼改變你的activity表就會成爲一個問題。

對大量表進行左連接也沒有意義。

,讓你有三種選擇:

  1. See this第一評論可能是有用的。

  2. 我猜你的活動表有一個名爲activity_type_id的字段。 構建名爲activity_types的表,其中包含字段activity_type_id,activity_name,activity_details_table_name。通過以下方式

    活動
    內第一個查詢加入
    activity_types
    使用(activity_type_id)

這個查詢就可以瞭解有關查詢的詳細信息表名。 這樣,您可以通過在activity_types表中添加一行來添加任何新的活動類型。

相關問題