2009-09-28 86 views
2

我有以下情形创建数据库模式中的问题:数据库设计问题

(我不是创建一个交友网站,但只是用这个作为一个例子)

用户登录到交友网站,并给出了头发的颜色多重选择,他们希望他们的日期有:

这是很容易与下面的三个表的模型:

表:

用户 {键}

染发 {键}

UserHairColour {用户键} {HairColourKey}

然而,用户也可以选择 '任意',这意味着他们不选择不关心头发颜色,所有的头发颜色都应该包含在选择中。

我该如何给用户提供'任何'选项?

我明显可以选择所有的头发颜色,并将它们推到'UserHairColour'中,但如果我将来需要添加新的头发颜色,该怎么办?

回答

9

的在UserHairColour表这一特定用户的任何记录缺失将表明他们不关心头发的颜色。

没有决定表明他们没有偏好。显然,这并不意味着他们希望自己的约会根本没有头发的颜色。

我没有看到这里需要一个单独的值或任何额外的表设计。你有什么可以让你以一种简单的方式实现你的目标。


编辑:作为对建议的解决方案与任何额外的价值的反应。

“ANY”的概念将在概念上干扰其他选择。我们正在讨论为用户提供多种选择,任何一个都是其中之一,并允许他们选择多个选项。因此,用户可以在技术上选择ANY以及其他选项,从而使其不清楚什么优先 - 任何或特定的选项。我相信没有任何记录作为ANY指标的方法更清晰 - 它只能以一种方式解释。没有记录 - 没有首选值。你显然不能以其他方式解释它 - 没有优先值 - 用户不希望这个值存在 - 这会使透明的头发颜色变得没有意义。你可以说它根本就没有头发,但我建议你有一个单独的选项或单独的问题。

+0

我认为这看起来是最实用的解决方案。这种方法的缺点是,应用程序将不得不做一个额外的旅行数据库。 E.g IF(User。PreferredHairColour.Count == 0) User。 PreferredHairColour =“select * from HairColour where UserKey = User.Key” (Not real code :-)) 谢谢 – 2009-09-28 13:37:11

+0

您的编辑让我重新更仔细地阅读了这个问题。我错过了“多选”意味着多个复选框而不是单选按钮的可能性。因此,如果用户可以选择Blonde + Brunette,那么您对Any的保留是合理的。但是,如果选择是独家的,那么我认为Any是一个有效的选择。 – APC 2009-09-28 19:53:45

+0

其实,即使有排他性的选择,“任何”选项都是多余的。 – 2009-09-28 20:31:41

0

声明一个临时表,使用颜色值和查询这样填写的:

SELECT * 
FROM UserHairColor 
JOIN User 
ON  User.id = UserHairColor.UserID 
WHERE HairColorKey IN 
     (
     SELECT ColorKey 
     FROM @mytable 
     ) 
UNION ALL 
SELECT * 
FROM UserHairColor 
JOIN User 
ON  User.id = UserHairColor.UserID 
     AND NOT EXISTS 
     (
     SELECT NULL 
     FROM @mytable 
     ) 

这将选择所有用户请求的发色,所有用户在所有如果表是空的。

1

鉴于上面的例子,我只想补充“的任何”或“无所谓”的选择,并把它作为一个特定的发色。这将最好的工作,因为如果你想添加更多特定的头发颜色。通常,当我创建新的关系模型时,我倾向于为第一个键条目添加-1,并将该行的值保留为默认值。 这将是更好的做法,只是在我看来用临时表或查询虚拟出来。

0

如果用户可以选择任意数量的HairColours,我认为,为了保持一致性,在UserHairColours中为每种颜色推送记录会很有用。如果用户只能选择一个,其中之一是'任何',那么我在城镇解决方案中赞成New。

0

将(PersonID,HairColorPreference)放在它自己的表中。如果有人没有偏好,就不要在该表中记录一行。

使用视图将偏好设置为偏好的人以及不偏好所有头发颜色的人。

顺便说一句,你打算怎么做,谁的偏好是“什么,但紫色”?

1

这应该很容易实现。如果用户选择“任意”,你只需处理它的查询:

select 
* 
from 
User 
left join 
UserHairColour on UserHairColour.UserId=User.UserId 
where 
(@hairpreference = 'Any' OR [email protected]) 

如果你可以设置输入VAR @hairpreference为null,而不是“任意”,那么它变得更容易:

where 
(UserHairColour.HairColourId=COALESCE(@hairpreference, UserHairColour.HairColourId)) 
0

显然,你不打算建立一个交友网站,你可以清楚地说明其他答案是否满足你的需求。但我的建议是创建另一张桌子,告诉用户是否选择了任何没有头发颜色的头发颜色(在您的示例中听起来是无稽之谈,但在其他情况下可能有意义)。 通过在数据库中有以下表格,您可以完成此操作。

  1. 用户
  2. 染发
  3. TypeOfColorSelection(1:选择的,2:全部,3:排除,...)
  4. UserColorSelectionProfile(用户ID,TypeOfColorSelection)
  5. UserPreferredColor(用户ID,染发)
+0

我认为'新的城镇'的答案解决了这个问题。这样做有点麻烦,我不得不使用事务来更新/插入表,并使用触发器来强制数据完整性。 – 2009-09-28 14:06:49

0

如果你想要头发颜色选项是强制性的,那么无选择(空套)选项不起作用。

0

这让我想起了Whiskas猫食的经典英国电视广告。该品牌标语本来,

八个十个业主说,他们 猫喜欢它

后来,又改为

八个十个业主谁表示 一个的偏好表示他们的猫 更喜欢它

[斜体是我的。]

显然,如果未能显示隐式明确无偏好之间的差异,那么结果就会出现偏差,否则为什么要更换不太适合扫描的扫描仪? QED;)

我偏好使用单独的表格来模拟那些表达偏好的人(以及他们选择的颜色),那些表示他们没有偏好的人以及那些没有偏好的人。

对于一个工作的例子,参见Hugh Darwen的How To Handle Missing Information Without Using NULL