2009-09-02 77 views
1

在我的應用程序中,用戶應該能夠定義可用日期。 IE瀏覽器。用戶joe可以定義他可用:
- 在2009年9月1日至2009年11月15日的每個星期一,星期三和星期日15:00至17:00之間。 - 於2009年9月2日12:00至14:00之間 依此類推......循環日期的表格設計

日期可能會定義爲將來最多1年。

用戶可以添加,編輯和刪除定義的日期。

其他用戶可以搜索可用用戶,即。 - 找到所有用戶可用8.09.2009在15:30

問題是如何設計sql表,它允許創建和編輯循環日期和高效搜索。

我使用postgresql,而是尋找任何指導。也許有人有類似的問題經驗?

在此先感謝

回答

1

當我已經處理數據,如在此之前,我已經採取了「規則」,類似這樣的方法,以適應由天調度和塊調度:

CREATE TABLE availability_rules (
    id SERIAL UNIQUE, 
    user_id NOT NULL REFERENCES users(id), 
    day_of_week INTEGER CONSTRAINT valid_day_of_week CHECK (day_of_week BETWEEN 0 and 6) 
    start_time TIME, 
    start_date DATE, 
    end_time TIME, 
    end_date DATE 
); 

注意:您需要然後,您可以創建一個「可用性」視圖,以用user_id,date,start_time和end_time生成一個規範化的時間表,然後在規則表中添加額外的約束條件。使用8.4,使用新的generate_series日期時間功能很容易。 (http://www.postgresql.org/docs/current/static/functions-srf.html)如果你使用8.3或更早的版本,編寫一個能夠完成相同任務的函數是很容易的。

+0

約束絕對是一個好主意。我目前的方法使用了generate_series,但是我擔心爲了彌補記錄而效率低下,不會使用索引。 – mlomnicki 2009-09-02 11:31:24

+0

我認爲你會沒事的。但是,爲了獲得最佳性能...您可以將視圖實現爲緩存可用性表,而不是一次更新整個事件,而是使用觸發器根據更改的規則以及如何選擇性地插入或更新。然後,您可以針對物化視圖進行查詢以獲得可用性,同時仍保持單獨的規則。 在走這條路線之前,我至少會對視圖進行一次EXPLAIN ANALYSE來衡量性能。 – 2009-09-02 12:32:54

+0

這絕對是最好的建議。但是我沒有發現任何關於'緩存可用性表'的信息。如何在postgres中處理它?請給我一個鏈接或任何基本的指導方針。 – mlomnicki 2009-09-02 13:13:41

0

你將要存儲在數據庫中的用戶的可用性和使用的編程語言來檢查的可用性,而不是在數據庫本身的任何複雜的邏輯。使用ORM工具會使這更容易。

用戶可用性將包含日期時間對列表。

+0

會有數百萬條記錄。恐怕在應用程序級別執行會太慢。 – mlomnicki 2009-09-02 11:00:54

1

選項1

你將存儲的可用性與3列(假設一個ID山坳來識別用戶)

availability_start, availability_end, user_id 

搜索基於日期時間,然後會像

select 
    user_id 
from 
    availability 
where 
    desired_datetime > availability_start 
and 
    desired_datetime < availability_end 

根據您想要提供的功能,您可能需要刪除過去的日期。顯然你需要根據人們的週期日期定義來決定存儲日期。

選項2

如果它始終是作爲選擇星期和時間對這些天的各天一樣簡單。您可以將循環日期存儲爲

user_id, day_of_week, availability_time_start, availability_time_end 

開始和結束時間不需要日期分量。搜索基礎上,一週中的一天和時間會是這樣的

select 
    user_id 
from 
    availability 
where 
    desired_day_of_week = day_of_week 
and 
    desired_time > availability_time_start 
and 
    desired_time < availability_time_end 

順便說一句,有其創建這樣重複日期的模式,我工作的地方,我們使用this協助圖書館(JAVA) ,可能會有適合您的語言的RFC 2445實現。

如果你使用類似的東西,那麼你將不會被存儲實際日期,但復發的模式,不會真正幫助你解決問題的只是細節。我們通過簡單地從遞歸定義中獲取這些值並將它們保持到db一個字段到一個列來存儲這些細節。

然後,您也可以將日期/時間存儲在未來的某個確定的時間內,並對重複定義的任何更改重新計算這些值,這顯然可能會變成相當大的操作,具體取決於人們有多少個時間表以及如何遠在將來你想存儲數據。

+0

我已經添加了關於最大日期的說明。據我所知RFC2445可能只用於導出日曆。我無法想象如何在數據庫中存儲icalendar格式並對其進行搜索。我喜歡簡單的想法,但我認爲它太簡單了。如何存儲和編輯循環日期? – mlomnicki 2009-09-02 11:27:26

+0

我已經添加了選項2,可能有幫助,並簡要提及我們如何堅持RFC 2445定義 – Robin 2009-09-02 11:50:07

0

你可以做的是有一個具有以下設計的表:

Availability 
    - userId, Foreign key to user table 
    - startDate, datetime 
    - endDate, datetime 
    - startTime, datetime 
    - endTime, datetime 
    - monday, bit 
    - tuesday, bit 
    - wednesday, bit 
    - thursday, bit 
    - friday, bit 
    - saturday, bit 
    - sunday, bit 

現在你可以檢查在某些平日可用性以下(MSSQL yntax)

SELECT * FROM User u WHERE EXISTS(
    SELECT 1 FROM Availability WHERE userId = u.id AND 
    @startDate >= startDate AND @endDate <= endDate AND 
    @startTime >= startTime AND @endTime <= endTime AND 
    (monday = 1 OR tuesday = 1) 
) 

哪會在星期一或星期二的@startTime和@endTime之間爲@startDate和@endDate提供所有可用的用戶。

+0

這是非常有趣的想法,我現在檢查它 – mlomnicki 2009-09-02 12:26:12