在 DB2 中将 table 扁平化为规范化 table
Flat table to normalized table in DB2
这适用于 DB2 9.7
--OLDPHONE TABLE
CREATE TABLE OLDPHONE (
ID BIGINT NOT NULL ,
PHONE1 VARCHAR(30) ,
PHONE2 VARCHAR(30) ,
PHONE3 VARCHAR(30) ,
PHONE4 VARCHAR(30) ,
PHONE5 VARCHAR(30));
--NEWPHONE TABLE
CREATE TABLE NEWPHONE (
ID BIGINT NOT NULL ,
INDEX SMALLINT NOT NULL ,
PHONE VARCHAR(30) NOT NULL);
--SAMPLE DATA
INSERT INTO OLDPHONE (ID, PHONE1, PHONE2, PHONE3, PHONE4, PHONE5) VALUES
(1,'78948418',NULL, NULL, NULL, NULL),
(2,'78948418','78948418', NULL, NULL, NULL),
(3,'78948418','78948418', '78948418', NULL, NULL),
(4,'78948418',NULL, NULL, '78948418', NULL),
(5,'78948418',NULL, '78948418', '78948418', NULL);
目前,使用 OLDPHONE
table 方法,客户最多可以拥有 5 个 phone 号码。我希望能够让客户存储未指定数量的 phone 个号码。因此,为了操作数据,我创建了 NEWPHONE
table 以将现有数据合并到其中。
我使用这个合并语句来获得我需要的结果,它工作得很好,但成本很高。有没有更有效的方法来做到这一点?定期执行此合并以更新 NEWPHONE
table。所以需要合并。
MERGE INTO NEWPHONE P1 USING (
SELECT T1.ID, T2.INDEX, T2.PHONE
FROM OLDPHONE AS T1,
TABLE(VALUES(1, T1.PHONE1),
(2, T1.PHONE2),
(3, T1.PHONE3),
(4, T1.PHONE4),
(5, T1.PHONE5))
AS T2(INDEX, PHONE)
WHERE T2.PHONE IS NOT NULL) P2
ON P1.ID = P2.ID AND P1.INDEX = P2.INDEX AND P1.PHONE = P2.PHONE
WHEN NOT MATCHED THEN
INSERT (ID, INDEX, PHONE)
VALUES (P2.ID, P2.INDEX, P2.PHONE);
是否真的需要合并,还是您可以直接插入?您的问题不清楚。
insert into newphone
select id, 1, phone1 from oldphone where phone1 is not null
union all
select id, 2, phone2 from oldphone where phone2 is not null
union all
select id, 3, phone3 from oldphone where phone3 is not null
union all
select id, 4, phone4 from oldphone where phone4 is not null
union all
select id, 5, phone5 from oldphone where phone5 is not null
如果插入性能不佳,可以加快速度的事情:
- 在事务中使用
alter table newphone activate not logged initially
禁用目标 table 上的日志记录。
- 如果这不起作用,请使用
LOAD FROM <cursorname>
,这几乎肯定是最有效的。
如果您确实需要合并,请尝试按照上面的建议禁用日志记录。另外,确保在合并的 on
子句中使用的每一列都有一个索引。
这适用于 DB2 9.7
--OLDPHONE TABLE
CREATE TABLE OLDPHONE (
ID BIGINT NOT NULL ,
PHONE1 VARCHAR(30) ,
PHONE2 VARCHAR(30) ,
PHONE3 VARCHAR(30) ,
PHONE4 VARCHAR(30) ,
PHONE5 VARCHAR(30));
--NEWPHONE TABLE
CREATE TABLE NEWPHONE (
ID BIGINT NOT NULL ,
INDEX SMALLINT NOT NULL ,
PHONE VARCHAR(30) NOT NULL);
--SAMPLE DATA
INSERT INTO OLDPHONE (ID, PHONE1, PHONE2, PHONE3, PHONE4, PHONE5) VALUES
(1,'78948418',NULL, NULL, NULL, NULL),
(2,'78948418','78948418', NULL, NULL, NULL),
(3,'78948418','78948418', '78948418', NULL, NULL),
(4,'78948418',NULL, NULL, '78948418', NULL),
(5,'78948418',NULL, '78948418', '78948418', NULL);
目前,使用 OLDPHONE
table 方法,客户最多可以拥有 5 个 phone 号码。我希望能够让客户存储未指定数量的 phone 个号码。因此,为了操作数据,我创建了 NEWPHONE
table 以将现有数据合并到其中。
我使用这个合并语句来获得我需要的结果,它工作得很好,但成本很高。有没有更有效的方法来做到这一点?定期执行此合并以更新 NEWPHONE
table。所以需要合并。
MERGE INTO NEWPHONE P1 USING (
SELECT T1.ID, T2.INDEX, T2.PHONE
FROM OLDPHONE AS T1,
TABLE(VALUES(1, T1.PHONE1),
(2, T1.PHONE2),
(3, T1.PHONE3),
(4, T1.PHONE4),
(5, T1.PHONE5))
AS T2(INDEX, PHONE)
WHERE T2.PHONE IS NOT NULL) P2
ON P1.ID = P2.ID AND P1.INDEX = P2.INDEX AND P1.PHONE = P2.PHONE
WHEN NOT MATCHED THEN
INSERT (ID, INDEX, PHONE)
VALUES (P2.ID, P2.INDEX, P2.PHONE);
是否真的需要合并,还是您可以直接插入?您的问题不清楚。
insert into newphone
select id, 1, phone1 from oldphone where phone1 is not null
union all
select id, 2, phone2 from oldphone where phone2 is not null
union all
select id, 3, phone3 from oldphone where phone3 is not null
union all
select id, 4, phone4 from oldphone where phone4 is not null
union all
select id, 5, phone5 from oldphone where phone5 is not null
如果插入性能不佳,可以加快速度的事情:
- 在事务中使用
alter table newphone activate not logged initially
禁用目标 table 上的日志记录。 - 如果这不起作用,请使用
LOAD FROM <cursorname>
,这几乎肯定是最有效的。
如果您确实需要合并,请尝试按照上面的建议禁用日志记录。另外,确保在合并的 on
子句中使用的每一列都有一个索引。