我在为以下场景创建数据库架构时遇到问题:
(我不是创建一个约会网站,而只是以此为例)
用户登录约会网站并获得他们想要的日期颜色的多重选择:
这很容易用以下三个表进行建模:
表:
用户 {密钥}
染发 {密钥}
UserHairColour {用户密钥} {HairColourKey}
但是,用户还可以选择“任意”,这意味着他们不关心头发颜色,所有头发颜色都应该包含在选择中。
如何为用户提供“任意”选项?
我显然可以选择所有的头发颜色并将它们推入'UserHairColour'但是如果我将来需要添加新的头发颜色怎么办?
答案 0 :(得分:9)
UserHairColour表中缺少此特定用户的任何记录将表明他们不关心头发颜色。
缺席决定表明他们没有偏好。显然,这并不意味着他们希望他们的约会根本没有发色。
我在这里看不到需要单独的值或任何额外的表设计。你拥有的东西可以让你以一种简单的方式实现你的目标。
编辑:作为对具有任何额外价值的建议解决方案的反应。
“ANY”的概念在概念上会干扰其他选择。我们正在讨论为用户提供多种选择,任何一种选择,并允许他们选择多种选择。因此,用户可以在技术上选择ANY以及其他选项,使得不清楚什么是优先级 - 任何或特定选项。我认为简单地没有记录作为ANY的指标的方法更清楚 - 它只能被解释为一种方式。没有记录 - 没有首选值。你显然不能用另一种方式解释它 - 没有首选值 - 用户不希望这个值存在 - 这将使透明的头发颜色毫无意义。你可以说它根本就没有毛发,但我建议你有一个单独的选项或单独的问题。
答案 1 :(得分:1)
鉴于上面的例子,我只想添加'Any'或'No Preference'作为选择,并将其视为特定的头发颜色。这将是最好的,因为如果你确实想要添加更具体的头发颜色。通常,当我创建新的关系模型时,我倾向于为第一个键条目添加-1,并将该行的值保留为默认值为1。 在我看来,这比使用临时表或查询虚拟出更好的做法。
答案 2 :(得分:1)
这应该很容易实现。如果用户选择“任何”,您只需在查询中处理它:
select
*
from
User
left join
UserHairColour on UserHairColour.UserId=User.UserId
where
(@hairpreference = 'Any' OR UserHairColour.HairColourId=@hairpreference)
如果您可以将输入var @hairpreference设置为null而不是'Any',那么它会变得更容易:
where
(UserHairColour.HairColourId=COALESCE(@hairpreference, UserHairColour.HairColourId))
答案 3 :(得分: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
)
如果表格为空,这将选择具有所请求头发颜色的所有用户。
答案 4 :(得分:0)
如果用户可以选择任意数量的HairColours,我认为,为了保持一致性,在UserHairColours中为每种颜色推送记录会很有用。如果用户只能选择一个,其中一个是“任意”,那么我更喜欢New in town的解决方案。
答案 5 :(得分:0)
将(PersonID,HairColorPreference)放在自己的表中。如果某人没有偏好,则不要在该表中记录一行。
使用视图将具有偏好的人与仅有偏好的人放在一起,并将没有偏好的人与所有染发颜色放在一起。
顺便说一下,对于那些偏爱“除了紫色之外”的人,你打算怎么办?答案 6 :(得分:0)
显然,你不打算建立一个交友网站,你可以说清楚这里的其他答案是否满足你的需要。但我的建议是创建另一个表来判断用户是否选择了任何头发颜色都没有(在你的例子中听起来很废话但在其他情况下可能有意义)。 通过在数据库中包含以下表格,您可以完成此任务。
答案 7 :(得分:0)
如果您希望头发颜色选项是必需的,则无选择(空集)选项不起作用。
答案 8 :(得分:0)
这让我想起了Whiskas猫粮的经典英国电视广告。背带最初是
十分之八的业主说他们的 猫更喜欢它
后来,它被改为
表达了十分之八的所有者 一个偏好说他们的猫 喜欢它
[斜体是我的。]
显然,当未能显示隐式明确地没有偏好之间的差异时,结果会出现偏差,否则为什么要为不能完全扫描的那个更改一个不完美的好标语呢? QED;)
我倾向于使用单独的表来模拟表达偏好的人(以及他们选择的颜色),表达他们没有偏好的人和不表达偏好的人。
有关实例,请参阅Hugh Darwen的How To Handle Missing Information Without Using NULL。