2012-05-04 80 views
3

我的數據庫存儲版本號;然而,它們有兩種格式:major.minor.build(例如8.2.0,12.0.1)和日期(例如YY-MM-DD)。我曾想過兩種解決方案:同一列的不同類型

+---+---+-----+-----------+ +-----+-----+-----+-----+ +-----+--------+ 
|...|...|id |versionType| |id |major|minor|build| |id |date | 
|---+---+-----+-----------| |-----+-----+-----+-----| |-----+--------| 
|...|...|12345|0   | |12345|0 |1 |2 | |21432|12-04-05| 
|---+---+-----+-----------| +-----+-----+-----+-----+ +-----+--------+ 
|...|...|21432|1   | 
+---+---+-----+-----------+ 

+---+---+-----+-----+-----+-----+--------+ 
|...|...|id |major|minor|build|date | 
|---+---+-----+-----+-----+-----+--------| 
|...|...|12345|0 |1 |2 |null | 
|---+---+-----+-----+-----+-----+--------+ 
|...|...|21432|null |null |null |12-04-05| 
+---+---+-----+-----+-----+-----+--------+ 

這些都不看起來特別有效:第一,需要在兩個表聯接只是爲了獲得一個版本號,而第二廢物兩倍與第一個版本相比,每個版本條目有很多空間或者,我可以將該值存儲在一列中的某些位上,然後在客戶端解釋該值,但我希望對於這種情況有一些標準實踐,我忽略了這一點。

有沒有一種合適的方法來爲關係數據庫中的同一'列'存儲兩種不同類型的數據?

+3

存儲在一個字符串? –

+1

我不是SQL忍者,但我會愉快地將這些值存儲在一個varchar列中。你是否真的需要將它分佈在一些表格中,還是僅僅爲了規範化而做? – brandizzi

回答

0

我不認爲這裏有一顆銀彈。如果你堅持有一個單獨的列,你可以天真地將它們都拍成一個CHAR(10),儘管這有它自己的問題(例如無效日期或格式不正確的內部編號字符串等)。

我認爲關鍵的問題是你想要運行什麼類型的查詢,以及你期望有多少行?

我會讓預期的查詢需要驅動數據庫設計。

+1

每次查詢一行(其中,最多有四到五千;實際上大約兩個),則需要版本號。 ...我想這是浪費空間和避免正常化,以減少毫無意義的聯接是有道理的。 – Casey

0

第一個比較好。如果您覺得每次進行連接都會讓您頭痛,那麼您可以創建一個視圖(使用連接)並使用該視圖,而不是直接使用表(或每次進行連接)。

0

可能您可以將數據存儲在一個int/bigint字段中。但在這種情況下,您必須轉換所有值: 日期 - 將其轉換爲從某日期開始的天數,或者可能使用unixtimestamp 版本 - 限制構建的值(讓它爲最大值1000),次要(1000)。 =主要* 1000 * 1000 +次要* 1000 +生成

0

我會去第二個選項,因爲表格的顆粒是一個版本,不管它是怎麼進來的。將它存儲在3個數字列和1個日期列在Oracle數據庫中應該只有每行16個字節(每個數字和日期列4個字節)。如果你的數據庫處理虛擬(計算)列,你可以添加一個類似於nvl(to_char(date),major ||'。'|| minor ||'。'|| build)的列,並且總是從數據庫中選擇數據格式化爲一個varchar或者你可以在其上放置一個視圖。

0

這實際上取決於你想如何在查詢中使用這個版本號。 如果足以將版本號作爲標籤對待,那麼您應該考慮將其存儲在varchar列中。

如果這還不夠,而且您希望能夠對版本號進行排序,則事情會變得更加複雜,因爲將版本號存儲爲保留自然排序順序的數據類型會更方便。我可能會用你的解決方案2.是否有理由擔心效率?你期待數以百萬計的行嗎?如果沒有,那麼你可能不應該太擔心。

如果空間,速度和體積是確定的考慮因素,您可以考慮將實際版本號存儲爲文本標籤,並導出代理版本號(單個整數),並將其存儲在單獨的列中,用於分類目的。

另一方面,如果事實證明一些對象有版本日期,一些版本號,有時兩者,我仍然會考慮你的第二個解決方案。如果你真的想要一個超級規範化的模型,你可以考慮創建單獨的version_date和version_number表,它們與對象表有1:1的關係。而你仍然需要這些連接。雖然 - 沒有理由擔心這一點:數據庫擅長連接,這是他們做得很好的原因。

0

是你的情況,你有不同種類的版本化對象,其中一種版本控制使用日期,另一種版本控制使用版本號,或者你的情況是同一種類型的對象版本是引用使用日期和使用版本號?

在第一種情況下,不要打擾創建這樣一個不起任何有用目的的仿真表。只有在解決真正存在的業務問題時才需要創建表,並且從版本日期到版本號的翻譯或反之亦然在此情況下不存在。即使它出現以後,那麼你仍然可以...

在第二種情況下,定義表像在你的第二個選擇,但:

沒有所有那些愚蠢的毫無意義的ID。請留下四列maj/min/bld/date。並且不要讓它們爲空。定義兩個鍵:maj/min/bld和日期。爲每個新版本註冊一行,記錄構建的創建日期(/ activation/whatever ...)。使用maj/min/bld構造作爲任何表中描述您所管理的版本化對象的版本指示符,並且每當請求進入使用日期完成版本引用時,通過查詢將其解析爲版本號你的4列表。