2009-06-26 17 views
0

我們都同意數據庫用於存儲,並且代碼不應與其緊密結合。如何在數據庫中存儲首選項時實現此目標。讓我舉個例子。挑戰 - 保持代碼和數據行分離

假設您正在創建一個小在線調查。每個民意調查可以有一個「投票類型」。下面是一些票種:

  • 匿名投票
  • 基於
  • 葉投票

現在如果有就是用戶創建一個投票和存儲「投票式」的界面,似乎不可避免的是,在某些時候,您將db(主鍵或名稱)中的某些內容與「匿名投票」「基於IP的投票」的代碼相關聯等。

在不同的但涉及d question,約翰桑德斯說這很愚蠢 - 我完全同意他的看法!爲什麼連接數據庫和代碼 - 這是一個壞主意。但是如果你存儲類似「投票類型」的東西,你如何避免它?

回答

1

只需定義一些常量,無論它們是枚舉還是支持任何語言,例如

enum VoteType { Anon = 1, IP = 2, ... } 

有在與常量的值數據庫中的表投票表決類型列。如果要強制在你的數據庫的引用完整性然後創建與相關值的查找表,否則不中,這種情況只是數據庫中不透明的一塊數據。

這裏沒有比具有標題列的輪詢表更多的耦合了。這是您需要存儲的民意調查的一個方面,所以只需存儲它。

+0

這讓我感到不舒服......但是如果你問我,這就好像它變得越來越好。我很想聽到更好的答案(因爲我自己碰到了這個)。 – Beska 2009-06-26 18:38:38

0

糾正我,如果我錯了,但你不能只在你的Polls table存儲vote_type field?如果vote_type是ip,則使用storeVoteByIP()函數。如果它是userID,則使用storeVoteByID()方法 - 或使用開關的一種方法。

也許我只是幼稚,但是我沒有看到這裏的挑戰:)

switch($vote_type) { 
    case 1: 
    #insert_vote_by_ip(); 
    break; 
    case 2: 
    #insert_vote_by_userid(); 
    break; 
    ... 
} 

我缺少什麼?

+1

實際上有很多方法可以做到這一點。這個特定的解決方案遭受了這樣一個事實,即你正在掩埋id'vote_type'和代碼之間的連接,以便在任意一段代碼中運行。我嘗試過的一種方法是讓一個類註冊「ip」與它連接的事實,然後向知道這一點的經理註冊自己。對此批評請參閱: 我列出了其中三個http://stackoverflow.com/questions/1050062/suggested-architecture-for-associating-code-to-db-rows。 – Daniel 2009-06-26 18:37:03

-2

要做的一件事就是將首選項作爲XML存儲到數據庫的XML列中。那麼數據庫並不關心存儲的內容 - 取決於代碼。

+0

現在,這有什麼問題?我非常成功地完成了此操作,將首選項序列化爲數據庫列。我還使用了配置源提供程序,它從數據庫中取出配置設置,而不是磁盤上的文件。 downvoters可能會給出關於這個答案有什麼問題的線索? – 2009-06-26 22:33:25

0

代碼的數據結構與數據庫結構之間需要有一些連接。爲了避免混用應用程序代碼和數據代碼而試圖避免這種情況是不值得的 - 您需要以最一般的可能方式設計代碼和數據。這對於某些應用程序可能是必需的(設計一個讓用戶設計數據結構的應用程序),但很可能不是您想要的許多其他應用程序 - 您是否真的想要查詢數據庫來了解投票表的結構?每列有多少列?列的名稱是什麼?

保持一個整潔有組織的應用程序的一個好方法是維護一個組件,表和應用程序代碼都從中繪製它們的值。

因此,對於您的示例,您可以使用一些靜態最終字段設計VoteTypes類。要訪問真正去到數據庫中的值的名稱,您的代碼將調用

getAnonVotingTypeName() getIpBasedVotingTypeName() 等。

這樣,如果名稱有所變動,我們只需要在一個類中更改它們(當然,更新表中的現有記錄)。

0

你可以有一個枚舉。在C#中,是這樣的:

public enum VoteType 
{ 
    ANONYMOUS, 
    IP_BASED, 
    OTHER 
} 

,然後在你的代碼簡單地說,像

switch(vote.Category) 
{ 
    case VoteType.ANONYMOUS: //do stuff 
    case VoteType.IP_BASED: //do some other stuff 
    //etc 
} 

這比使用基於字符串更好的,它避免了拼寫錯誤之類的東西的一些錯誤。

0

的主要原因解耦代碼和數據是,在某些時候,你可能要以不同的方式呈現數據。在這一點上,如果你將代碼和數據緊密結合在一起,你將不得不做很多工作來剝離它。

另一個原因是,它是很難被擊敗的難易程度使得在文本文件中,而不是數據庫代碼的變化。

所以,如果你確信的發言將永遠不會改變,你知道一個簡單的方法,讓您的代碼是最新的,是不是真的有很大的原因讓他們分開。

但是,很難看到這種情況。

0

存儲的偏好/配置可以是一個好主意,如果他們改變很oftenly,就像如果你有一個良好的頻率創建新的投票類型。另一方面,如果新的投票類型對你的模型非常重要(例如當基於IP的投票有一個完整的系統來獲得統計數據,或許多與之相關的業務邏輯)時,他們有權利被提拔到實體類等

但我不認爲你可以從你的代碼完全分離的數據庫,只是因爲數據庫在你的源代碼(尤其是當你在事務中工作)的影響。

0

讓我們假設你創建一個類,它實際搞清楚VoteType應該做的(所以它能夠檢測你的is_another_vote_available)的辛勤工作等,所以你可以有:

  • VoteTypeIpSingleVote:這一個允許每IP地址投一票
  • VoteTypeAnonymous:這個投票沒有限制。

在DB你就必須在VoteType表條目:

  • 1單一IP投票
  • 2個匿名

然後,您可以做一個接口,所有VoterTypes(VoteTypeAnonymous等等)實現具有屬性「VoteType」,其返回

a)行t的主鍵嘿與 b)一個枚舉類型,其散列是主鍵 c)通過在設置表中查找找到的主鍵(這具有數據庫和代碼之間的連接可供所有人)

這種方法的優點是你可以擁有一個每個VoterTypes註冊的管理器類(甚至可以使用反射自動註冊)。

所以,你可以撥打:

ID = fetchVoteTypeToBeUsedFromDb

manager.getVoteType(ID).is_available(datetime.now())

而且這樣新VoteTypes可能只是通過無縫地添加註冊自己,而不必持續更新switch語句。