关于连接和表的问题与数百万行

时间:2010-05-01 19:36:43

标签: sql mysql database postgresql

我必须创建2个表:

杂志(这些列有1000万行:id,标题,流派,印刷,价格)

作者(包含这些列的1.8亿行:id,name,magazine_id)

。 每个作者都只能写一本杂志,每本杂志都有更多的作者。

因此,如果我想了解Motors Magazine的所有作者,我必须使用此查询:

SELECT * FROM Author, Magazine WHERE ( Author.magazine_id = Magazine.id ) AND ( genres = 'Motors' )

同样适用于“打印和价格”栏目。

为了避免与数百万行的表连接,我想使用这个表:

杂志(此列有1000万行:id,标题,流派,印刷,价格)

作者(此列有1.8亿行:id,name,magazine_id,流派,打印,价格)

。 和这个查询:

SELECT * FROM Author WHERE  genres = 'Motors' 

这是一个好方法吗?

我想让它跑得更快

我可以使用Postgresql或Mysql。

5 个答案:

答案 0 :(得分:6)

不,我不认为如您所描述的那样复制信息对于关系数据库来说是一个很好的设计。

如果您更改特定杂志的类型或价格,则必须记住在重复信息的所有作者行中更改它。如果您有时忘记,最终会导致数据异常。你怎么知道哪一个是正确的?

这是relational database normalization的一个好处,用于表示冗余最小的信息,因此您不会出现异常。

为了让它跑得更快,我想你要做的是,你应该学习how to use indexes,尤其是covering indexes

答案 1 :(得分:3)

如果您只需要获取杂志的作者(并且没有关于杂志的信息),您可以使用EXISTS。有人说EXISTS比JOIN快,因为EXISTS在第一次点击后停止搜索。然后你应该使用:

SELECT *
FROM Author
WHERE EXISTS (SELECT 1 FROM Magazine WHERE genres = 'Motor' AND Author.id = Magazine.id)

另外,如前所述,指定列会加快速度。

答案 2 :(得分:2)

  

这是一个好方法吗?

     
  1. 这种方法的优点超过了缺点。去标准化的缺点(这就是你提出的建议)包括:   
        
    • 您需要随时更改magazine_id,为作者表中的每个杂志保留正确的流派,打印和价格数据。这太贵了。   
    • 你显然浪费了更多的存储空间,平均每次重复18次杂志数据(这是正确的猜测吗?)。   
    • 任何其他选择/维护作者表变得更慢/更昂贵。   
     
  2. 您的查询似乎已损坏。它应该是  
     SELECT * FROM Author, Magazine 
     WHERE Author.magazine_id = Magazine.id AND genres = 'Motors'
     
     
  3. 要解决您的问题,请确保您在杂志表上有关于流派的索引和关于authors表上的magazine_id的索引

答案 3 :(得分:1)

你应该这样做:

SELECT * FROM Author
JOIN Magazine ON Author.id = Magazine.id
WHERE genres = 'Motors'

这应该很快。如果它太慢,请确保您拥有所有相关索引,包括所有表的id字段上的主键索引和genres上的索引。

您还应列出所需的列,而不是返回所有列。请注意,此查询可能会返回数百万行。你确定要取得所有这些吗?我会考虑使用分页和只获取前50个的解决方案,直到用户请求查看下一页。

答案 4 :(得分:1)

您不需要进行JOIN,即使这样您的基本查询也是错误的。你想说:

SELECT name FROM author
WHERE magazine_id in 
    (SELECT id FROM magazine WHERE genres = 'motors')

管理这样的大型数据存储有许多不同的方法。如果您举例说明您希望从这些数据中获得什么,那么人们可以建议有效的方法。