我很感兴趣,为什么多对多关系比将信息存储在一行中更好。
示例:我有两个表,用户和电影(非常大的数据)。我需要建立一个关系“视图”。 我有两个想法:
我感兴趣的是哪种方法更好,为什么。请考虑数据非常大。
答案 0 :(得分:1)
第二种方法几乎在所有方面都更好。您不仅可以利用数据库索引更快地查找记录,还可以使修改变得更加容易。
答案 1 :(得分:1)
方法1)可以通过使用像“...field_in_set(movie_id, user_movielist) ...
”这样的SQL来回答“哪些电影有用户X观看过”的问题。但反过来说(“哪个用户确实看过电影x”)将无法在sql基础上运行。
这就是为什么我总是采用方法2):明确规范化结构,两种方式都是简单的连接。
答案 2 :(得分:0)
这只是你的需求。如果您需要性能,则必须接受信息的冗余并添加一列。如果您的主要目标是尊重规范化范例,那么您根本就不应该有冗余。 当我必须做这种选择时,我会尝试估计冗余的空间损失与感兴趣的查询的频率及其性能。
答案 3 :(得分:0)
还有一些想法。
在您第一种情况下,如果您查找特定用户,您可以轻松获取他们所看到的电影的ID列表。但是,那么需要一个单独的查询来获取这些电影的标题等细节。这可能是一个查询使用IN与id列表,或每个电影ID一个查询。这将是低效和笨重的。
使用MySQL,可能会使用FIND_IN_SET()函数加入这种情况(尽管这样做的一个缺点是你正在考虑非标准SQL)。您可以使用ON FIND_IN_SET(film.id,users.film_id)>将您的电影表加入到用户手中。 0。然而,这不会使用连接的索引,并且涉及一个函数(虽然快速执行它的操作,但在数千行上执行时会很慢)。
如果你想找到所有观看过特定用户观看过的电影的用户,那就更难了。您不能只使用FIND_IN_SET,因为它需要单个字符串和逗号分隔列表。作为单个查询,您需要将特定用户加入到电影表中以获取大量中间行,然后再次将其连接到用户(使用FIND_IN_SET)以查找其他用户。
SQL中有一些方法可以拆分以逗号分隔的值列表,但它们很混乱,任何必须维护此类代码的人都会讨厌它!
这些都是软糖。使用第二个解决方案,这些操作很容易,而且任何生成的连接都可以轻松使用索引(并且可能整个查询只需使用索引而无需触及实际数据)。
第一个解决方案的另一个问题是数据整合。您必须手动检查胶片是否为用户显示两次(使用第二种解决方案,可以使用唯一键轻松实施)。您也不能只添加外键以确保用户的任何电影ID确实存在。此外,您必须手动确保在分隔的ID列表中没有任何内容输入字符串。