在 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 子句中使用的每一列都有一个索引。