您可能会从一张表中获得稍微更好的性能,但此决定应主要取决于数据或约束的性质是否不同。
您必须做出另一个(从性能角度来看更重要的)决定:您希望如何对数据进行集群(所有InnoDB 表都是集群的)?
如果您想在获取给定页面的所有链接时获得出色的性能,请使用标识关系,在链接表中生成自然键:
![在此处输入图像描述](https://i.stack.imgur.com/i0imn.png)
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
一个例子。