在 Teradata 中为具有 one-to-one 关系的表插入策略

Insert strategy for tables with one-to-one relationships in Teradata

在源自 Teradata 行业模型的数据模型中,我们观察到一种常见模式,其中逻辑数据模型中的超类和子类关系被转换为 one-to-one [=44] 之间的关系=] 和 child table。

我知道您可以 roll-up 或 roll-down 属性以单个 table 结束,但我们总体上不使用此选项。最后我们得到的是这样一个模型:

其中城市 ID 引用地理区域 ID。

我正在努力寻找一个好的策略来加载这些 table 中的记录。

选项 1: 我可以 select max(Geographical Area Id) 并计算批量插入的下一个 ID,并将它们重新用于城市 Table.

选项 2: 我可以在地理区域中使用身份列 Table 并在插入每条记录后检索它,以便将其用于城市 table.

还有其他选择吗?

我需要从性能、可靠性和维护方面评估解决方案。

如有任何意见,我们将不胜感激。

亲切的问候,

保罗

当您说 "load the records into these tables" 时,您是在谈论一次性数据迁移还是为新地理 Area/City 创建记录的功能?

如果您要查找代理键并且可以接受 ID 值中的间隙,则使用 IDENTITY 列并指定 NO CYCLE 子句,这样它就不会重复任何数字。然后把值传NULL,让TD来处理。

如果您确实需要顺序 ID,那么您只需维护一个单独的 "NextId" table 并使用它来生成 ID 值。这是最灵活的方式,可以让您更轻松地管理 BATCH 操作。它需要更多 code/maintenance,但比对数据 table 执行 MAX() + 1 以获得下一个 ID 值更有效。基本思路如下:

开始交易

  • 通过查找获取 "next" ID table
  • 使用该值为您的下一条记录生成新的 ID 值
  • 创造你的新记录
  • 更新查找 table 中的 "next" ID 值并将其增加新插入的 # 行(您可以通过直接将值存储在 ACTIVITY_COUNT 值变量中来捕获它在执行你的 INSERT/MERGE 语句后)
  • 确保在交易开始时锁定查找 table,以便在交易完成之前无法修改它

结束交易

这是一个来自 Postgres 的例子,你可以适应 TD:

CREATE TABLE NextId (
    IDType VARCHAR(50) NOT NULL,
    NextValue INTEGER NOT NULL,
    PRIMARY KEY (IDType)
);

INSERT INTO Users(UserId, UserType)
SELECT 
    COALESCE(
        src.UserId, -- Use UserId if provided (i.e. update existing user)
        ROW_NUMBER() OVER(ORDER BY CASE WHEN src.UserId IS NULL THEN 0 ELSE 1 END ASC) + 
        (id.NextValue - 1) -- Use newly generated UserId (i.e. create new user)
    )
    AS UserIdFinal,
    src.UserType
FROM (
    -- Bulk Upsert (get source rows from JSON parameter)
    SELECT src.FirstName, src.UserId, src.UserType
    FROM JSONB_TO_RECORDSET(pUserDataJSON->'users') AS src(FirstName VARCHAR(100), UserId INTEGER, UserType CHAR(1))
) src
CROSS JOIN ( 
    -- Get next ID value to use
    SELECT NextValue
    FROM NextId 
    WHERE IdType = 'User'
    FOR UPDATE -- Use "Update" row-lock so it is not read by any other queries also using "Update" row-lock
) id
ON CONFLICT(UserId) DO UPDATE SET
UserType = EXCLUDED.UserType;

-- Increment UserId value
UPDATE NextId
SET NextValue = NextValue + COALESCE(NewUserCount,0)
WHERE IdType = 'User'
;   

只需将锁定语句更改为 Teradata 语法(LOCK TABLE NextId FOR WRITE)并在 INSERT/MERGE 之后添加一个 ACTIVITY_COUNT 变量以捕获受影响的 # 行。这假设您在存储过程中执行所有这些操作。

告诉我进展如何...