我们都同意db用于存储,并且代码不应与它紧密耦合。当您在数据库中存储首选项时,如何实现此目的。让我举个例子。
假设您正在创建一个小型在线投票。每个民意调查都可以有“投票类型”。以下是一些投票类型:
现在,如果有一个用户创建轮询并存储“投票类型”的界面,那么在某些时候你似乎不可避免地将数据库中的某些东西(主键或名称)与代码相关联'匿名投票''基于IP投票'等。
在一个不同的,但相关的question中,约翰桑德斯说这很愚蠢 - 我完全同意他的意见!为什么连接数据库和代码 - 这是一个坏主意。但是,如果你存储像“投票类型”这样的东西,你如何避免呢?
答案 0 :(得分:1)
只需定义一些常量,无论它们是枚举还是您支持的语言,例如:
enum VoteType { Anon = 1, IP = 2, ... }
在数据库的Poll表中有一个投票类型列,其中包含常量值。如果要在数据库中强制执行参照完整性,则创建一个包含相关值的查找表,否则不创建,在这种情况下,这些是只是数据库中不透明的数据。
这里没有比Poll表更多的耦合,比如标题。这是你需要存储的民意调查的一个方面,所以只需存储它。
答案 1 :(得分:0)
如果我错了,请纠正我,但你不能只在vote_type field
中存储Polls table
吗?如果vote_type是ip,则使用storeVoteByIP()
函数。如果是userID
,则使用storeVoteByID()
方法 - 或使用带切换的一种方法。
也许我只是天真,但我没有看到这里的挑战:)
switch($vote_type) {
case 1:
#insert_vote_by_ip();
break;
case 2:
#insert_vote_by_userid();
break;
...
}
我错过了什么?
答案 2 :(得分:0)
代码的数据结构与数据库结构之间需要有一些联系。为了不混合应用程序代码和数据代码而试图避免这种情况是不值得的 - 您需要以最一般的方式设计代码和数据。对于某些应用程序(设计允许用户设计数据结构的应用程序),这可能是必要的,但可能不是您想要的其他许多应用程序 - 您是否真的希望查询数据库以了解您的投票表的结构?每个有多少列?列的名称是什么?。
维护整洁有序的应用程序的一个好方法是维护一个组件,表和应用程序代码都可以从中获取它们的值。
因此,对于您的示例,您可以设计一个带有一些静态最终字段的VoteTypes类。要访问实际进入数据库的值的名称,您的代码将调用
getAnonVotingTypeName() getIpBasedVotingTypeName() 等。
这样,如果名称发生了变化,你只需要在那个类中更改它们(当然,更新表中的现有记录)。
答案 3 :(得分: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
}
这比使用基于字符串更好,它避免了一些错误拼写和类似的错误。
答案 4 :(得分:0)
将代码和数据分离的主要原因是,您可能希望以不同的方式呈现数据。那时,如果你有紧密耦合的代码和数据,你将不得不做很多工作来剥离它。
另一个原因是很难在文本文件而不是数据库中轻松地进行代码更改。
因此,如果您确定演示文稿永远不会改变,并且您知道一种简单的方法可以使代码保持最新,那么确实没有什么理由将它们分开。
但是,很少见到这种情况。
答案 5 :(得分:0)
如果他们经常更改,存储首选项/配置可能是一个好主意,例如,如果您创建频率很高的新投票类型。
另一方面,如果新的投票类型对您的模型非常重要(例如基于Ip的投票有整个系统来获取统计数据,或者与之相关的许多业务逻辑),他们有权利成为晋升为实体,班级等。
但我认为您不能完全将数据库与代码分离,只是因为数据库会对您的源代码产生影响(特别是在处理事务时)。
答案 6 :(得分:0)
让我们假设您创建了一个实际上正在努力弄清楚VoteType应该做什么的类(因此它可以检查诸如is_another_vote_available之类的东西)等等。所以你可以拥有:
在数据库中,您将在VoteType表中有条目:
然后,您可以创建一个所有VoterTypes(VoteTypeAnonymous等)实现的接口,该接口具有返回的属性“VoteType”
a)与其关联的行的主键 b)枚举类型,其哈希是主键 c)通过在设置表中进行查找而找到的主键(这样做的好处是每个人都可以访问数据库和代码之间的连接)
这种方法的优点是你可以拥有一个每个VoterTypes注册的管理器类(或者甚至可以使用反射自动注册)。
所以你可以打电话:
id = fetchVoteTypeToBeUsedFromDb
manager.getVoteType(id).is_available(datetime.now())
通过注册自己而不必连续更新switch语句,可以无缝添加新的VoteTypes。
答案 7 :(得分:-2)
要做的一件事就是将首选项作为XML存储到数据库中的XML列中。然后数据库不关心存储什么 - 这取决于代码来解决它。