Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询项目(包括其链接数据)的最佳做法_Sql_Database_Database Design_Amazon Redshift - Fatal编程技术网

Sql 查询项目(包括其链接数据)的最佳做法

Sql 查询项目(包括其链接数据)的最佳做法,sql,database,database-design,amazon-redshift,Sql,Database,Database Design,Amazon Redshift,数据库包含一个与另一个表具有一对多关系的表。第一个表有许多列,第二个表只有几列–例如,在这个数据库设计中: ┌───────────────────┐ │item │ ├───────────────────┤ │id: BIGINT │←┐ │name: VARCHAR(100) │ │ │ ... │ │ │<many attributes> │ │ │ ... │ │ └───

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

┌───────────────────┐
│item               │
├───────────────────┤
│id: BIGINT         │←┐
│name: VARCHAR(100) │ │
│ ...               │ │
│<many attributes>  │ │
│ ...               │ │
└───────────────────┘ │
                      │ 
┌───────────────────┐ │
│item_tag           │ │
├───────────────────┤ │
│item_id: BIGINT    │─┘
│name: VARCHAR(100) │
│color: VARCHAR(50) │
└───────────────────┘
问题在于,表项有许多列包含大量数据,因为该项中的每一行在查询结果中都会出现多次。许多数据必须通过网络传输到客户端。此外,客户端必须合并具有相同项目数据的所有行,以获得每个项目的相应标记

可能的解决办法2

首先查询项目

SELECT * FROM item;
…然后检索每个项目的标记:

SELECT * FROM item_tag WHERE item_id = ?;
但这需要多个单独的SQL查询——每个项目行一个查询——这可能会很慢;还由于每个查询请求的网络延迟

可能的解决办法3

两个表都查询一次

SELECT * FROM item;
SELECT * FROM item_tag;
…标记到项目的映射由客户端完成

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

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


我更喜欢使用有限的数据库功能的解决方案,这些功能没有那么多奇特的功能,比如数组类型。

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

如果您希望选择尽可能少的行数,并不惜一切代价避免重复,一种方法是将item_标记表中的值串联起来,并按item id进行分组,这样您就可以将一个item与所有对应的item_标记放在一行中。老实说,我不能告诉你收益是多少,这要看情况而定。正如你所描述的,可能是3。但尝试这三种方法并对其进行测量不需要太多的努力。如果进入选项3,您还可以考虑通过ItMeSIDID对每个结果集进行排序,给客户端一个简单的合并连接来实现对象。用它来找出你有多少个带有特定标记集或其他有趣问题的项目更有意义。您是否有要使用红移优化的特定查询?谢谢您的建议@盖伊:我使用*只是为了保持示例查询的简单,在现实世界中,我会选择一个数据子集。但基本上,应该检索数据以显示在一个列表中,想象一下一个包含项目的表,其中最后一列包含相应标记的列表,允许用户浏览项目。目前不存在表模式,我只考虑一个。通常,基于文档的数据库适用于此特定情况,但不能使用,因为存在其他数据仓库数据,此数据应与组合。您不限于单个数据存储。在一个数据存储MySQL或MongoDB中使用类似于标记的元数据,并在红移中使用事件/日志数据。
SELECT * FROM item;
SELECT * FROM item_tag;