2009-06-25 38 views
9

我們必須保存每年一次的重複事件的日期和月份。 (把它當作他們當年的發票發送給客戶的那一天。)在數據庫中僅保存日期和月份的最佳方式

我們將不得不使用這些信息做一些計算。例如,如果客戶每年支付兩次。那麼我們不僅需要檢查今天是否是今天,而且如果這一天是在6個月內。

我們現在有幾種選擇: a)我們將信息保存在日期字段中,但忽略年份。 b)我們在數據庫date_day和date_month中創建兩個int字段。 c)我們創建一個varchar字段,然後做一個正則表達式和分割例如每次我們做一些計算時,每次都會增加31.12。

我們做了幾個測試,發現c)肯定太慢了。但我們仍然有選擇a)和b)。首先我們想要去b),但經過一些測試後,我們更傾向於a)。

是否有一個很好的技術原因會真正使一個選項比另一個好得多?

(我們使用目前的MySQL,如果這是很重要的。)

回答

9

我會選擇B),因爲它更準確地反映了數據的含義。有一些數據結構中的某些部分應該被「忽略」是有問題的。如果人們只是簡單地進行日期比較,假設年份總是相同,但是有人使用了不同的佔位符年份,假設年份無關緊要?

始終使用反映您意圖的數據結構。

這c)是壞的,我相信,超出合理的討論:-)。我並沒有想到性能的原因...

+0

同意,其在那裏它的部分都應該被忽略的數據字段是非常糟糕的,很可能會在未來咬你。我投贊成票b。 – 2009-06-25 10:55:30

+0

是的,這一年並不重要。我們已經有合同開始日期和合同結束日期。我們只需要計算是否必須發送發票。我們正在做的第一個選擇是檢查「今天」是否在開始日期和結束日期之內。只有這樣我們才能檢查我們是否必須今天生成發票。 – 2009-06-25 14:01:54

0

我也想與b),但使用TINYINT的月份(0至255)和SMALLINT(-32,768至32,767)爲一年,以節省一點空間。

0

選擇一個int字段,如1月1日的1601。

+0

這個選項和「31.12」有什麼區別? – 2009-06-25 10:55:38

+0

計算而不是字符串操作 – 2009-06-25 11:02:00

+0

正確,但你也可以把它作爲一個實數存儲 – 2009-06-25 11:20:44

1

我會選擇b),因爲這會使查詢變得更加容易:您將能夠以非常簡單的方式恢復範圍內(12月,特定日期,日期範圍)內的所有事件。 如果您選擇a) - 爲了比較和提取的原因,不要忘記將年份設置爲特定的年份。

2

我會使用日期字段,即使不需要,仍然可以節省一年。只需將其打印出來/使用它即可。有幾個方面的原因:

  1. 你可能會發現,後面的 點的客戶不希望你 保存日期。在這種情況下,您不需要對您的 數據庫結構進行任何更改。
  2. 如果需要,您可以使用SQL日期函數來比較日期。如果您的日期和月份位於不同的字段中,則需要更多代碼計算兩個日期(閏年等)之間的差異。

選擇b)的原因也可以用SQL日期函數輕鬆解決。例如,在一個查詢中,您可以輕鬆選擇某個月的事件。

1

我會存儲第一個事件的日期,然後每個後續事件的間隔,有點像大多數日曆應用程序。在這種情況下,你會構建這樣的:

first_event | interval | interval_unit 
-------------+-------------------------- 
    2009-01-01 |  6 | 'month' 
    2009-02-01 |  1 | 'year' 

不幸的是,MySQL不具有INTERVAL數據類型,所以兩列,一位後處理的將是必要的,但我認爲這是最靈活的方式來解決問題。

0

我會去天的年數(例如,從0到365,然後單號添加到特定年份的1月1日你感興趣的內容。

如果您不想做上面的解決方案的額外數學,然後使用兩個字段一個月和一個日期(但確保您在需要時更新兩個!)。

請記住,您必須處理閏年,所以使用日期字段是一個壞主意,因爲你必須存儲兩年的日期 - 一個閏年,一個不是 - 非常複雜!

1

我也面對sa我的問題,在我的情況,我需要根據特定的日期在一個月內被重複。我每年用於「日期」和這樣的查詢

SELECT * FROM test_table WHERE MONTH(date) = 1 AND DAY(date) = 14

結果這樣

enter image description here檢索數據

優勢

  1. 我可以使用MySQL的能力。
  2. 減少客戶端計算。
  3. 可以使用DATE_FIELD其他計算

我的建議是用這種方式

,這可能是有幫助的人

相關問題