2012-02-06 27 views
4

我們正在爲我們的創業構建一個調度系統。需要數據庫架構瘋狂的最佳方法

這只是一個普通的,除了我們願意實現的「自動查找」功能。燈架構。沒什麼特別的。

這是DB的外觀。三個主要的表:

  • 辦事處(ID,START_TIME,STOP_TIME)
  • 人(ID,office_id,START_TIME,STOP_TIME)
  • 附表(ID,people_id,START_TIME,STOP_TIME)

start_time/stop_time是TIMESTAMPS。

表不需要這樣。這是只是我們目前有。

辦公室表具有辦公室的開/關時間。這個表格可能每個辦公室365天大,因爲開啓/關閉時間每天都不一樣。請注意,它可能高達1000個辦事處。這使得表中大約有365,000多條記錄。

有加入/離開時間。這顯然比辦公室更具限制性。同樣,一年中的每一天都可以有不同的訪問時間。每個辦公室都有大約50人。這使得1000個辦公室* 365天* 50名員工= 18,250,000條記錄。

時間表是誰會遇到誰。每個人每天最多可以有10次會議。是的,在這一點上,這個表格很容易製造出1825萬行。

除了數字沒什麼奇怪的。應用程序需要做的是:給定辦公室,見面人員和持續時間,顯示前5個可用日期。

從我們相信,這個程序將完全殺死我們的服務器。我們只是不顧一切地做這個運行。我們首先想到的是「這根本不可能」。但是,嘿!一切都可能在軟件中,不是嗎? PS:如果有人想到一個更好的方法,使應用程序可行,我們真的欣賞它。

非常感謝您的閱讀。希望一些硬核程序員可以借我們一把。

UPDATE:

出於測試目的,我們已經創建了兩個完全一樣的表:

會議&辦事處(ID,設備專業,啓動,停止)。

ID爲主,其餘爲BTREE索引。 SQL是這樣的(它不能100%工作):

SELECT a.profesional, a.stop AS desde, Min(b.start) AS hasta 
FROM meetings AS a 
    JOIN meetings AS b 
    ON a.profesional=b.profesional 
    AND a.stop < b.start 
WHERE a.profesional = 1 
    AND b.profesional = 1 
GROUP BY a.start 

UNION 

SELECT m.profesional, MIN(m.start), MIN(j.start) 
FROM offices m 
    JOIN meetings j 
    ON j.profesional = m.profesional 
WHERE j.profesional = 1 
    AND m.profesional = 1 

UNION 

SELECT m.profesional, MAX(j.stop), MAX(m.stop) 
FROM offices m 
    JOIN meetings j 
    ON j.profesional = m.profesional 
WHERE j.profesional = 1 
    AND m.profesional = 1 

ORDER BY desde ASC 

我們所做的是以下內容。 240天內只增加1個辦公室。每天有8次會議,總共約2000行。執行此類查詢需要2.6(!)秒。查詢是否錯誤?它可以重寫嗎?

+1

說明很明確,但如果您提供了列名和數據類型,則會更好。 – 2012-02-06 21:07:04

+0

對不起,我剛剛添加了架構。 – 2012-02-06 21:13:03

+0

您可能會考慮使用基於網絡的服務,例如Amazon或Cloud。 – alexy13 2012-02-06 21:14:52

回答

6

如果你給了一個人,是不是已經減少了計劃行的數量減少了50000倍?如果你只考慮給定的辦公室,辦公室的行數也將下降到幾百。一個適當的索引會很快找到你的那些行。

另外,人們是否真的提前安排了一整年的會議,或者是否更有可能在未來一兩個月內只有完整的數據庫?如果開始在主數據庫中出現性能問題,您可以隨時將舊數據移入存檔。

此外,「達到」估計很容易想到太大。你應該試着弄清楚每個辦公室將有多少人在平均和他們將有多少次會議平均。 「每天最多10次會議」可能很容易變成「通常每天兩次」。當然,取決於我們談論的是什麼類型的業務。

不要忘記減去週末。他們構成了今年的2/7。

+0

首先,非常感謝。我無法正確格式化評論,所以我會分解它們。爲了測試目的,我們創建了兩個完全相同的表格:會議和辦公室(id,專業,開始,停止)。 ID是主要的,其餘的是BTREE索引。SQL是這樣的(它不能100%工作) – 2012-02-06 21:45:36

+0

SELECT a.profesional,a.stop AS desde,Min(b.start)AS hasta FROM meeting AS a JOIN meeting AS b b ON a.profesional = b .profesional AND a.stop 2012-02-06 21:45:45

+0

我們已經完成了以下工作。 240天內只增加1個辦公室。每天有8次會議,總共約2000行。執行此類查詢需要3.1(!)秒。查詢是否錯誤?它可以重寫嗎?非常感謝!! – 2012-02-06 21:46:09

0

你的應用程序似乎需要一個關鍵的查詢。查找定義的時間間隔由

(OfficeOpenIntervals INTERSECT PeopleAtOfficeIntervals) MINUS ScheduleIntervals 

而在這些間隔搜索,附近還是有一定的日期之後。

使用適當的索引和限制查詢(僅搜索一個人,接下來的60天等)可能會很好。處理時間間隔操作是棘手的,但您可以使用各種索引和方式來編寫查詢。


另一種選擇(如果你測試,發現通過索引沒有有效的方式)是有一個單獨的AvailableSlots表這將是在第一,當沒有預定的約會,填充了所有可用天一個人在該辦公室(這將是OfficeOpenIntervals INTERSECT PeopleAtOfficeIntervals)。然後每次在Schedule中添加約會時,此AvailableSlots表中的對應行將被刪除,更新或拆分成兩行,以存儲預定會議的人員的剩餘可用間隔。

因此,顯示前5個可用日期的查詢只需要在此表中進行搜索。

這不是一個規範化的解決方案,完整性必須由存儲過程維護(對於所有操作(如添加日程表,離開辦公室的人,啓動等)。最初的人口也可能需要時間和空間 - 但是你不需要在一百年內填充表格。可能只有幾個月,稍後可以完成額外的人口(每月或每年一次或在需要時)。

+0

我真的很感謝你的消息ypercube。我們會試試看。非常感謝! – 2012-02-06 21:53:14