数据库包含一个与另一个表具有一对多关系的表。第一个表有很多列,第二的人只是少数 - 例如像在这个数据库设计:查询项目及其链接数据的最佳做法
┌───────────────────┐
│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的有限数据库功能的解决方案,它没有那么多花哨的特性,比如数组类型。
如果您想选择的行可能的最低数量,不惜一切代价避免重复,一个方法是由项目ID来连接从item_tag表和分组的值,这样你将有一个项目的所有相应的item_tag在一行中。我不能告诉你多少诚实的收益。 – 2014-08-30 19:20:45
这取决于。正如你所描述的那样,大概是3,但尝试所有三种方法并测量它不应该太费力。如果要为选择3,你也可以考虑每个排序结果由'item_id'设置,给客户一个简单的合并连接兑现的对象。 – Laurence 2014-08-30 20:12:02
不鼓励在像Redshift这样的分析数据库上选择*。使用它来查找具有特定标签集或其他“有趣”问题的项目数量会更有意义。你有一个你想用Redshift优化的特定查询吗? – Guy 2014-08-31 15:38:57