我的网站显示了不同主题的链接集合。这些链接分为两种类型:Web和图像。我的数据库将拥有数百万(可能超过一千万)这些记录。当页面加载时,我需要向用户显示该页面特定主题的Web和图像链接。所以第一个问题是:
我是否创建了两个单独的较小的表,每个表用于Web和图像链接,然后对每个表进行查询,或者为两者创建一个巨大的表(具有正确的索引)并进行一个查询。我会在哪里获得更好的表现?如果一个表和一个查询更有效,那么我的下一个问题是:
将两种类型细分为演示文稿的最有效方法是什么?我应该使用group by
,还是应该使用php将结果数组分成两种类型?
TIA!
答案 0 :(得分:3)
您可以使用所有对象的表格或链接或网站的表格获得类似的表现。如果您有两个单独的表,那么执行结果的UNION将返回您需要的所有结果。
划分结果的主要原因是它们是否真的不同(从您的应用角度来看)。也就是说,如果你最终会使用很多像
这样的查询select * from objects where type='image';
然后有两个表可能是有意义的。
然后使用group by不是对不同结果进行分组的一种方式,它是一种聚合它们的方式。
因此,例如,您可以使用
select type, count(*) from objects group by type
获取
| image | 100000 |
| web | 2000000 |
但它不会返回分隔的对象。要使它们“分组”,您可以对每个查询使用查询,也可以使用排序,然后在应用程序中使用逻辑来划分结果。
答案 1 :(得分:1)
这取决于网络数据如何接近img数据。如果数据基本上是由链接组成的,那么一个表更适合,有一个列可以区分Web和数据(以及后面可能有的其他表,如css,js ......)
Links: (id, link, type)
在类型或类型链接上添加索引将有助于分组(按类型)和匹配搜索(类型,链接)。
但是,如果网页和img数据不同,你不想混合苹果和橘子,比如
Web: (wid, wlink, rating, ...)
Img: (iid, ilink, width, height, mbsize, camera, datetaken, hasexif...)
在这种情况下,除了链接之外,两个表没有太多共同之处。图像链接和网络链接不同,当两种数据具有相同的链接时甚至没有“增益”。另一个优点(一个表也可以,但在这里更有意义)是在另一个表中链接两种数据
Relations: (wid,iid)
允许维护网站和图像之间的关系,因为图像可能被多个网站使用,并且网站使用多个图像。在wid
和iid
上建立索引。
我的偏好是两个表(带有可选的“关系”链接)。
关于来自PHP的查询,使用UNION
,您可以在一个查询中从两个表中获取数据。
答案 2 :(得分:1)
您可能只从一个表中获得略微更好的性能,但这个决定应该主要取决于数据或约束的性质是否不同。
还有另一个(从性能角度来看更重要)您必须做出的决定:您希望如何cluster数据(所有InnoDB tables are clustered)?
如果您想获得一个特定页面的所有链接的出色表现,请使用标识关系,在链接表中生成一个自然键:
LINK表实际上只是一个B树,页面PK 1 位于前沿,它将属于同一行的行物理组合在一起页。通过简单的索引范围扫描和最小I / O可以满足以下查询:
SELECT URL
FROM LINK
WHERE PAGE_ID = <whatever>
如果您使用单独的表,则可以只有两个不同的查询。许多客户端API支持在单个数据库往返中执行两个查询。如果PHP没有,你可以UNION两个查询来保存一个数据库往返:
SELECT *
FROM (
SELECT 1 LINK_TYPE, URL
FROM IMAGE_LINK
WHERE PAGE_ID = <whatever>
UNION ALL
SELECT 2, URL
FROM WEB_LINK
WHERE PAGE_ID = <whatever>
)
ORDER BY LINK_TYPE
以上查询将为您提供......
LINK_TYPE URL
1 http://somesite.com/foo.jpeg
1 http://somesite.com/bar.jpeg
1 http://somesite.com/baz.jpeg
...
2 http://somesite.com/foo.html
2 http://somesite.com/bar.html
2 http://somesite.com/baz.html
...
...在客户端级别很容易分开。
如果您没有使用单独的表,您可以在客户端级别通过扩展名分隔URL,或者在LINK PK中引入其他字段:{PAGE_ID,LINK_TYPE,URL},这应该进行以下查询非常有效:
SELECT LINK_TYPE, URL
FROM LINK
WHERE PAGE_ID = <whatever>
ORDER BY LINK_TYPE
请注意,PK中的字段顺序很重要,因此将LINK_TYPE放在最后会阻止DBMS 仅进行索引范围扫描。
1 无论它是什么;我只是以PAGE_ID
为例。
答案 3 :(得分:0)
我是创建两个单独的较小的表还是一个巨大的表?
去一张桌子。
将两种类型细分为演示文稿的最有效方法是什么?
取决于某些搜索条件。