如何有效地将数据从垂直数据库布局传输到水平数据库布局
-
21-08-2019 - |
题
我想从垂直数据库布局传输数据,如下所示:
--------------------- | ID | Type | Value | --------------------- | 1 | 10 | 111 | --------------------- | 1 | 14 | 222 | --------------------- | 2 | 10 | 333 | --------------------- | 2 | 25 | 444 | ---------------------
到水平的:
--------------------------------- | ID | Type10 | Type14 | Type25 | --------------------------------- | 1 | 111 | 222 | | --------------------------------- | 2 | 333 | | 444 | ---------------------------------
创建布局不是问题,但数据库相当大,有数百万个条目,如果花费太多时间,查询就会被取消。
如何才能有效地完成此操作(以便查询不被取消)。
解决方案
with t as
(
select 1 as ID, 10 as type, 111 as Value from dual
union
select 1, 14, 222 from dual
union
select 2, 10, 333 from dual
union
select 2, 25, 444 from dual
)
select ID,
max(case when type = 10 then Value else null end) as Type10,
max(case when type = 14 then Value else null end) as Type14,
max(case when type = 25 then Value else null end) as Type25
from t
group by id
返回你想要什么,我认为这是更好的办法。 注意,最大函数只是这里由条款来执行组,任何一组函数可以是使用此处(如求和,分钟...)
其他提示
把它分解成更小的块,不裹在一个单一的交易,整个事情。首先,创建表,然后做从旧表插入组到新表。由ID的范围插入,例如,在足够小的块,它不会压倒数据库的日志和花费太长的时间。
垂直表——也称为实体-属性-值反模式——总是成为一个问题,有时在付诸实践后不久。如果您还没有这样做,请查看 Joe Celko 对这种策略的看法,您会看到更多证据来证明这种方法有多么麻烦。我就到此为止,因为您是知道访问此站点的聪明人,而不是在您的数据库中破坏 EAV 表的有罪但善意的一方。
处理这种类型的表的选项并不漂亮,而且,正如您所说,随着生产查询所需的数据量的增长,它们会变得更糟/更慢。
构建一个未记录并保留已提交行的已声明全局临时表 (DGTT),并使用它来暂存 EAV 表内容的水平版本。DGTT 非常适合这种数据挖掘,因为它们不会产生任何日志记录开销。
采用传统的 CASE 和 MAX() 分组,如前面的建议所示。问题在于,每次将新类型引入 EAV 表时,查询都会发生变化。
使用DB2 的SQL-XML 发布功能将垂直数据转换为XML。以下是使用您提供的表名和列名的示例:
WITH t(id, type, value) as (
VALUES (1,10,111), (1,14,222), (2,10,333), (2,25,444)
)
SELECT
XMLSERIALIZE( CONTENT
XMLELEMENT(NAME "outer",
XMLATTRIBUTES(id AS "id"),
XMLAGG(XMLELEMENT(NAME attr ,
XMLATTRIBUTES(type as "typeid"), value) ORDER BY type)
) AS VARCHAR(1024)
)
FROM t as t group by id;
SQL-XML 方法的优点是 EAV 表处理的任何新值都不需要重写用于转换这些值的 SQL。
不隶属于 StackOverflow