查询项目(包括其链接数据)的最佳实践



数据库包含一个与另一个表具有一对多关系的表。第一个表有很多列,第二个表只有几列——例如,在这个数据库设计中:

┌───────────────────┐
│item               │
├───────────────────┤
│id: BIGINT         │←┐
│name: VARCHAR(100) │ │
│ ...               │ │
│<many attributes>  │ │
│ ...               │ │
└───────────────────┘ │
                      │ 
┌───────────────────┐ │
│item_tag           │ │
├───────────────────┤ │
│item_id: BIGINT    │─┘
│name: VARCHAR(100) │
│color: VARCHAR(50) │
└───────────────────┘

检索所有项目行及其标记名称和标记颜色的最佳做法是什么?例如,将它们显示在带有标记的项目列表中。

可能的解决方案1

加入项目id:的两个表

SELECT * FROM item JOIN item_tag ON id = item_id;

这是一个问题,表中有许多列包含大量数据,因为项目的每一行都会在查询结果中多次出现。许多数据必须通过网络传输到客户端。此外,客户端必须将具有相同项目数据的所有行合并,以获得每个项目的相应标记。

可能的解决方案2

首先查询项目…

SELECT * FROM item;

…然后检索每个项目的标签:

SELECT * FROM item_tag WHERE item_id = ?;

但这需要多个单独的SQL查询——每个行一个——这可能很慢;也是由于每个查询请求的网络延迟。

可能的解决方案3

两个表都查询一次…

SELECT * FROM item;
SELECT * FROM item_tag;

…并且标签到项目的映射由客户端完成。

在这里,查询的数量和传输的数据量是尽可能少的,但客户端需要额外的处理工作。如果只查询的子集,则可以修改选择项目标签s的查询,以仅返回查询项的标签。


对此,还有其他/更好的解决方案吗?最好的方式是什么?

我更喜欢使用Amazon Redshift有限的数据库功能的解决方案,它没有太多花哨的功能,比如数组类型。

如果您已经知道要拾取哪些项,那么您可以在item_tag表中的item_id上创建一个索引,并使用第一个解决方案。如果平均而言,每个项目都有很多标签,这将节省您在item_tag表中查找大量行的时间。否则,如果您过于担心要传输的数据量,并且需要所有项目的结果,那么解决方案3似乎是合适的,因为将传输最小量的数据,但必须在客户端实现连接逻辑。因此,没有最好的解决方案。这完全取决于形势。

最新更新