好的,我知道技术答案是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中的 as-is :
$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个多选列呢?
所以,在这种情况下,如果我使用逗号分隔值,它真的很糟糕吗?
**** ****鸭
答案 0 :(得分:7)
你已经知道了答案。
首先,您的PHP代码甚至不能正常工作,因为它仅在用户2在LookingFor或Drugs中只有一个值时才有效。如果这些列中的任何一个包含多个以逗号分隔的值,则即使这些值与用户1的值完全相同,IN也将无效。如果右侧有一个或多个逗号,IN会做什么?
因此,在PHP中做你想做的事情并不“简单”。它实际上非常痛苦,并且会将用户2的字段拆分为单个值,编写带有许多OR的动态SQL来进行比较,然后执行效率极低的查询来获得结果。
此外,您甚至需要编写PHP代码以回答关于两组交集的相对简单的问题这一事实意味着您的设计存在严重缺陷。这正是SQL存在要解决的问题(关系代数)。正确的设计允许您解决数据库中的 问题,然后在PHP或其他技术中简单地实现表示层。
正确地做,你会有更轻松的时间。
答案 1 :(得分:1)
假设用户1正在寻找'挂出','友谊',用户2正在寻找'友谊','挂出'
你的代码不匹配,因为'友谊','挂出'不在('挂出','友谊')
这是真正的问题。