【发布时间】:2011-11-23 00:44:54
【问题描述】:
好的,我知道技术答案是NEVER。
但是,有时它似乎用更少的代码和看似很少的缺点让事情变得如此简单,所以请告诉我。
我需要构建一个名为 Restrictions 的表来跟踪人们希望联系的用户类型,并且该表将包含以下 3 列(为简单起见):
minAge
lookingFor
drugs
lookingFor 和 drugs 可以包含多个值。
数据库理论告诉我应该使用连接表来跟踪用户可能为其中任一列选择的多个值。
但似乎使用逗号分隔值使事情更容易实现和执行。这是一个例子:
假设 用户 1 有以下限制:
minAge => 18
lookingFor => 'Hang Out','Friendship'
drugs => 'Marijuana','Acid'
现在假设 用户 2 想要联系 用户 1。好吧,首先我们需要看看他是否符合用户 1 的限制,但这很容易,即使使用逗号分隔的列,如下所示:
首先我会得到目标(用户 1)的限制:
SELECT * FROM Restrictions WHERE UserID = 1
现在我只是将它们放入各自的变量中按原样放入 PHP:
$targetMinAge = $row['minAge'];
$targetLookingFor = $row['lookingFor'];
$targetDrugs = $row['drugs'];
现在我们只检查 SENDER(用户 2)是否符合这个简单的条件:
COUNT (*)
FROM Users
WHERE
Users.UserID = 2 AND
Users.minAge >= $targetMinAge AND
Users.lookingFor IN ($targetLookingFor) AND
Users.drugs IN ($targetDrugs)
最后,如果 COUNT == 1,用户 2 可以联系 用户 1,否则他们不能。
那有多简单?它看起来真的很简单直接,那么只要每次用户更新他们的联系限制时我都会清理数据库的所有输入,那么这样做的真正问题是什么?能够使用 MySQL 的 IN 函数并且已经以它可以理解的格式存储多个值(例如逗号分隔值)似乎比必须为每个多选列创建连接表要容易得多。我举了一个简化的例子,但是如果有 10 个多项选择列呢?如此多的连接表导致事情开始变得混乱,而 CSV 方法则保持简单。
那么,在这种情况下,如果我使用逗号分隔值真的那么糟糕吗?
****鸭子****
【问题讨论】:
-
它似乎看起来非常简单明了,而且确实可能如此。另一种解决方案(有许多 JOIN)可能看起来很困难且不简单——实际上它可能很困难且不简单。但它具有链接(您已经阅读过)描述的所有其他优势,例如速度、完整性执行等。
-
我的建议是:再次阅读该链接。
-
基本经验法则:如果您需要访问逗号分隔列表的任何单个部分,请不要使用逗号分隔列表。这样做首先破坏了使用关系数据库的意义。您已将数据呈现为非关系型,因此现在数据库已缩减为一个非常大/昂贵的哑存储系统。
-
我真的不明白
Users.lookingFor IN ($targetLookingFor)将如何匹配用户A 的'Hang Out,Friendship'和用户B 的'Friendship,Football' -
@Programmer:当然,你有一个选择——你可以跳过做正确的事情来完成工作,现在它可以工作了。但是,如果该站点值得该死的话,您稍后会投入时间,因为用户会想要更多的东西。比如说,推荐的联系人。为了实现它,您将不得不围绕数据库的限制编写一些代码。到最后,您将用 PHP 编写一个半笨的数据库引擎,并且只是将 MySQL 用作相对昂贵的原始数据存储。相信我,我去过那里。一点都不好玩。
标签: php mysql database database-design normalization