它叫做
database normalization.具体来说你需要映射一个
“Many to Many” association
你需要3张桌子.
User(id, name)
Language (id, language_name)
User_Language(id,id_user,id_language)
获取用户ID 3的所有语言:
SELECT l.language_name
FROM User u
JOIN user_language ul ON (u.id=ul.id_user)
JOIN Language l ON (l.id = ul.id_language)
WHERE u.id = 3
编辑:
注意@silkAdmin有两件事是很重要的.第一个,正如@ BryceAtNetwork23所说,没有必要在User_Language表上放置一个id.第二个是,你应该学习joins,特别是MySQL Joins(因为SQL在不同的数据库引擎中往往会有所不同).再挖一点之后,您将能够看到在上一个查询中加入User表也不需要,可以简化为:
SELECT l.language_name
FROM user_language ul
JOIN Language l ON (l.id = ul.id_language)
WHERE ul.user_id = 3
但我在第一个答案中添加了它,以便让您更轻松.
为什么使用语言表
我的回答只是反映了我这样做的方式.有很多方法可以完成所要求的.说,我解释自己.
让我们思考极端.第一个极端是将语言存储在用户表中,如上所述.例如,我们可以有一个列,并用分号分隔值.像这样的东西
User: (1, "John", "spanish;english;japanese")
这样做的好处是您不需要任何连接.鉴于您的用户的ID,您可以获得语言.缺点是搜索它真的很痛苦.如何使用“西班牙语”语言获得所有用户? (这里的底线是您无法索引数据).现在有点老的另一个缺点是过度使用磁盘空间.在发明数据库和规范化的时候,磁盘空间真的很昂贵.所以,存储这个:
User: (1, "John", "spanish;english;japanese")
User: (2, "Mary", "spanish;english")
这是无法容忍的事情.所以,有些人过来说:“嘿,让我们使用id,所以,我们可以把它变成”:
User: (1, "John", "1;2;3")
User: (2, "Mary", "1;2")
Language (1,"spanish")
Language (2,"english")
对于10.000个用户和几百种语言,这是磁盘使用量的巨大改进(可能在我们的时代,这不再是真的,我将在稍后讨论).这解决了磁盘问题,但我们仍然存在搜索问题.再次,如何让您的所有用户使用“西班牙语”语言?好吧,使用这种设计,你应该迭代用户表并获取语言列,将其拆分为“;”并寻找id 1.
这就是我们开始使用之前向您展示的方法的原因.
所以,到目前为止一切顺利.很好的解释;)
大免责声明
正如我之前所说,有几种方法可以做到这一点.这取决于你的情况,你想要实现什么.如果你想搜索该栏目(例如,给我说英语的用户)你应该考虑我在答案的顶部告诉你的设计.
现在有一个数据解决方案的“新浪潮”被称为no-sql数据库(它变化),试图对数据进行非规范化.如果您担心模式的过度规范化,那么您应该看一下.我推荐你MongoDB和CouchDB,因为那些更容易入手.
关于加入
不要担心2个连接的性能.如果你遇到性能问题,那就不是这个了.数据库引擎就是为此而创建的.凭借良好的内存缓存和索引优化,它应该可以顺利运行.