2014-08-30 54 views
0

数据库包含一个与另一个表具有一对多关系的表。第一个表有很多列,第二的人只是少数 - 例如像在这个数据库设计:查询项目及其链接数据的最佳做法

┌───────────────────┐ 
│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; 

...和标签的物品的映射是由客户端来完成。

这里查询的数量和传输的数据量是尽可能低的,但客户端的额外处理工作是不必要的。如果仅询问项目的子集,则可以修改用于选择item_tag的查询以仅返回查询项目的标签。


有没有其他更好的解决方案?什么是最好的方式去?

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

+0

如果您想选择的行可能的最低数量,不惜一切代价避免重复,一个方法是由项目ID来连接从item_tag表和分组的值,这样你将有一个项目的所有相应的item_tag在一行中。我不能告诉你多少诚实的收益。 – 2014-08-30 19:20:45

+0

这取决于。正如你所描述的那样,大概是3,但尝试所有三种方法并测量它不应该太费力。如果要为选择3,你也可以考虑每个排序结果由'item_id'设置,给客户一个简单的合并连接兑现的对象。 – Laurence 2014-08-30 20:12:02

+0

不鼓励在像Redshift这样的分析数据库上选择*。使用它来查找具有特定标签集或其他“有趣”问题的项目数量会更有意义。你有一个你想用Redshift优化的特定查询吗? – Guy 2014-08-31 15:38:57

回答

0

如果您已经知道要选择哪些项目,则可以在item_tag表中的item_id上创建一个索引并使用第一个解决方案。如果平均而言,每个项目都有很多标签,这将节省您在item_tag表格中查找很多行。否则,如果你太在意被传输的数据量和需要的所有项目的结果,那么解决方案3似乎是恰当的,因为数据的最小量将被转移,但加盟的逻辑将必须在客户端实现。所以,没有最好的解决方案。这完全取决于情况。

相关问题