事实表中的外键参照完整性 - T-SQL

Posted

技术标签:

【中文标题】事实表中的外键参照完整性 - T-SQL【英文标题】:Foreign key referential integrity in the fact tables - T-SQL 【发布时间】:2017-07-11 18:17:30 【问题描述】:

我有这个事实表:

CREATE TABLE [dbo].[FACT_TABLE]
(
    [A_id] [int] NOT NULL,
    [B_id] [int] NOT NULL,
    [C_id] [int] NOT NULL,
    [D_id] [int] NOT NULL,
    [FACT_total] [float] NOT NULL,
    [FACT_average] [float] NOT NULL,

    CONSTRAINT [PK_FACT_TABLE] 
        PRIMARY KEY CLUSTERED ([A_id] ASC, [B_id] ASC,
                               [C_id] ASC, [D_id] ASC)
) ON [PRIMARY]

我有一个 T-SQL 脚本可以将数据加载到我的事实表中:

INSERT INTO [dbo].[FACT_TABLE] ([A_id], [B_id], [C_id], [company_id], [D_id],[FACT_total], [FACT_average])
    SELECT 
        b.A_id, c.B_id, d.C_id, e.D_id,
        AVG(FACT_total) AS FACT_total,
        AVG(FACT_average) AS FACT_average
    FROM 
        [dbo].[staging_Area] a
    INNER JOIN 
        [dbo].[DIM_A] b ON a.A_id = b.A_id
    INNER JOIN 
        [dbo].[DIM_B] c ON a.[B_id] = c.B_id
    INNER JOIN 
        [dbo].[DIM_C] d ON a.[C_id] = d.C_id 
    INNER JOIN 
        [dbo].[DIM_D] e ON a.D_id = e.D_id
    GROUP BY  
        b.A_id, c.B_id, d.C_id, e.D_id 

如何保证不会在事实表中插入重复值以避免出现引用完整性错误?

我在查询之后尝试了以下语句:

EXCEPT 
SELECT *
FROM [dbo].[FACT_TABLE] 

但我认为这不是最好的方法......

有人对此有其他选择吗?抱歉,我不能输入真正的列名和表名...

谢谢!

【问题讨论】:

你如何定义你的副本?如果是整条记录,则将所有列作为复合键 【参考方案1】:

LEFT OUTER JOINWHERE FT.Column IS NULL 到 Fact 表,以确保您没有插入已经存在的记录:

INSERT INTO [dbo].[FACT_TABLE] ([A_id],[B_id],[C_id],[company_id],[D_id],[FACT_total],[FACT_average])
SELECT b.A_id
        ,c.B_id
        ,d.C_id
        ,e.D_id
        ,AVG(FACT_total) AS FACT_total
        ,AVG(FACT_average) AS FACT_average
FROM [dbo].[staging_Area] a
INNER JOIN [dbo].[DIM_A] b ON
    a.A_id = b.A_id
INNER JOIN [dbo].[DIM_B] c ON
    a.[B_id] = c.B_id
INNER JOIN [dbo].[DIM_C] d ON
    a.[C_id] = d.C_id 
INNER JOIN [dbo].[DIM_D] e ON
    a.D_id = e.D_id
LEFT OUTER JOIN dbo.[FACT_TABLE] FT
    ON b.A_ID = FT.A_id
    AND c.B_id = FT.B_id
    AND D.C_ID = FT.C_id
    AND E.D_id = FT.D_id
WHERE FT.A_ID IS NULL
GROUP BY  b.A_id
        ,c.B_id
        ,d.C_id
        ,e.D_id

【讨论】:

其实DISTINCT是多余的。由于您已经在分组,因此您无法获得重复项。我将编辑答案以将其删除。【参考方案2】:

插入 [dbo].[FACT_TABLE]

([A_id], [B_id], [C_id], [D_id],[FACT_total], [FACT_average])

选择 a.A_id、a.B_id、a.C_id、a.D_id、a.FACT_total、a.FACT_average

来自

( 选择

b.A_id, c.B_id, d.C_id, e.D_id,
AVG(FACT_total) AS FACT_total,
AVG(FACT_average) AS FACT_average

来自

[dbo].[staging_Area] a

内联

[dbo].[DIM_A] b ON a.A_id = b.A_id

内联

[dbo].[DIM_B] c ON a.[B_id] = c.B_id

内连接 [dbo].[DIM_C] d ON a.[C_id] = d.C_id

内联

[dbo].[DIM_D] e ON a.D_id = e.D_id

分组方式

b.A_id, c.B_id, d.C_id, e.D_id 

)a 

在哪里

不存在

( 从 dbao.FACT_TABLE B 中选择 1

在哪里 B.A_id = A.A_id AND B.B_id = A.B_id and b.C_id=a.C_id and b.D_id=a.D_id

   )

【讨论】:

你应该格式化这个,@alen - 它实际上是不可读的。

以上是关于事实表中的外键参照完整性 - T-SQL的主要内容,如果未能解决你的问题,请参考以下文章

参照完整性-外键约束

Oracle系统表外键的更名

SQL Server中常用的SQL语句

MySql外键

SQL Server中常用的SQL语句(转):

mysql外键