如何在事实表中添加多个外键?附SQL代码求错误排查
你的SQL代码中的错误分析与修正方案
我帮你排查出了代码里的语法和逻辑问题,下面逐一说明并给出修正后的完整代码:
错误点详解
- 表创建顺序错误:
Sales_FT引用了Store_DT,但你先创建了事实表再创建这个维度表。SQL Server要求被外键引用的表必须先存在,否则约束无法创建。 - 数据类型不匹配:外键列的数据类型必须和对应主键完全一致(包括长度)。比如
Sales_FT里的Store_ID定义为[char](无指定长度),但Store_DT的Store_ID是[char](10),长度不匹配会导致外键创建失败。同理Customer_ID、Bouquet_ID、Occasion_ID都存在这个问题。 - 列定义缺少逗号:
Sales_FT中各个外键列的定义之间没有逗号分隔,这是语法错误,会直接导致SQL解析失败。 - 表名拼写错误:外键引用里写的
OccasionDT是错的,正确表名是Occasion_DT。 - 事实表缺少主键:虽然不是强制要求,但数据仓库中的事实表通常需要复合主键(比如结合日期和各维度外键)来保证记录唯一性。
修正后的完整SQL代码
-- 先创建所有维度表,确保被引用的表先于引用它的表存在 CREATE TABLE [dbo].[Bouquet_DT]( [Bouquet_ID] [char](10) NOT NULL PRIMARY KEY, [Flowers] [varchar](50) NULL, [Color] [varchar](50) NULL, [Size] [varchar](50) NULL, [Cost_per_Unit] [numeric](10, 2) NULL ) CREATE TABLE [dbo].[City_DT]( [City_ID] [char](10) NOT NULL PRIMARY KEY, [City_Name] [varchar](50) NULL ) CREATE TABLE [dbo].[Customer_DT]( [Customer_ID] [char](10) NOT NULL PRIMARY KEY, [Customer_Name] [varchar](50) NULL, [Customer_Address] [varchar](50) NULL, [Customer_City] [char](10) NULL, [CNIC] [varchar](50) NULL, [Gender] [varchar](50) NULL, [Age] [numeric](5, 0) NULL, [Customer_PhoneNo] [varchar](50) NULL ) CREATE TABLE [dbo].[MembershipCard_DT]( [Card_ID] [char](10) NOT NULL PRIMARY KEY, [Discount%] [numeric](10, 2) NULL, [Duration_in_Years] [numeric](10, 0) NULL, [Price] [numeric](10, 2) NULL ) CREATE TABLE [dbo].[Occasion_DT]( [Occasion_ID] [char](10) NOT NULL PRIMARY KEY, [Occasion_Name] [varchar](50) NULL ) CREATE TABLE [dbo].[Store_DT]( [Store_ID] [char](10) NOT NULL PRIMARY KEY, [Store_Manager] [varchar](50) NULL, [Store_Address] [varchar](50) NULL, [Store_Area] [varchar](50) NULL, [Store_City] [char](10) NULL ) -- 最后创建事实表,此时所有被引用的维度表已存在 CREATE TABLE [dbo].[Sales_FT]( [Date] [datetime] NOT NULL, [Unit_Quantity] [numeric](10, 0) NULL, [SalePrice_Per_Unit] [numeric](10, 2) NULL, [Membership_Type] [char](10) NULL, -- 统一列名大小写风格,提升可读性 [Discount] [numeric](10, 2) NULL, [Delivery_Charges] [numeric](10, 2) NULL, -- 统一列名大小写风格 [Store_ID] [char](10) NOT NULL FOREIGN KEY REFERENCES [dbo].[Store_DT]([Store_ID]), [Customer_ID] [char](10) NOT NULL FOREIGN KEY REFERENCES [dbo].[Customer_DT]([Customer_ID]), [Bouquet_ID] [char](10) NOT NULL FOREIGN KEY REFERENCES [dbo].[Bouquet_DT]([Bouquet_ID]), [Occasion_ID] [char](10) NOT NULL FOREIGN KEY REFERENCES [dbo].[Occasion_DT]([Occasion_ID]), -- 添加复合主键,保证事实表记录的唯一性 PRIMARY KEY ([Date], [Store_ID], [Customer_ID], [Bouquet_ID], [Occasion_ID]) )
额外建议
- 列名尽量保持统一风格,比如全部用下划线分隔的小写(或大写),避免大小写混合,提升代码可读性。
- 外键列建议设置为
NOT NULL(除非业务允许事实表记录不关联某个维度),保证数据完整性。 Membership_Type看起来应该关联MembershipCard_DT的Card_ID,如果是这样,建议把该列改为Card_ID并添加外键约束关联维度表。
内容的提问来源于stack exchange,提问作者Shahzaib
相关产品推荐
相关产品推荐

