具有到多个表的外键关系的复合主键。 SQL Server 2008错误

时间:2010-08-20 21:33:06

标签: sql-server-2008 database-design

USE [Fk_Test2]
GO

/****** Object:  Table [dbo].[Owners]    Script Date: 08/20/2010 16:52:44 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Owners](
    [Owner] [varchar](10) NOT NULL,
 CONSTRAINT [PK_Owners] PRIMARY KEY CLUSTERED 
(
    [Owner] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO


/****** Object:  Table [dbo].[Key]    Script Date: 08/20/2010 16:49:57 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Key](
    [owner] [varchar](10) NOT NULL,
    [key_id] [varchar](10) NOT NULL,
    [description] [varchar](10) NOT NULL,
 CONSTRAINT [PK_Key] PRIMARY KEY CLUSTERED 
(
    [owner] ASC,
    [key_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Key]  WITH CHECK ADD  CONSTRAINT [FK_Key_Owners] FOREIGN KEY([owner])
REFERENCES [dbo].[Owners] ([Owner])
GO

ALTER TABLE [dbo].[Key] CHECK CONSTRAINT [FK_Key_Owners]
GO



/****** Object:  Table [dbo].[Bldg]    Script Date: 08/20/2010 16:50:29 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Bldg](
    [bldg] [varchar](10) NOT NULL,
    [owner] [varchar](10) NOT NULL,
 CONSTRAINT [PK_Bldg] PRIMARY KEY CLUSTERED 
(
    [bldg] ASC,
    [owner] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Bldg]  WITH CHECK ADD  CONSTRAINT [FK_Bldg_Owners] FOREIGN KEY([owner])
REFERENCES [dbo].[Owners] ([Owner])
GO

ALTER TABLE [dbo].[Bldg] CHECK CONSTRAINT [FK_Bldg_Owners]
GO


/****** Object:  Table [dbo].[KeyToBuilding]    Script Date: 08/20/2010 17:13:52 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[KeyToBuilding](
    [owner] [varchar](10) NOT NULL,
    [bldg] [varchar](10) NOT NULL,
    [key_id] [varchar](10) NOT NULL,
 CONSTRAINT [PK_KeyToBuilding] PRIMARY KEY CLUSTERED 
(
    [owner] ASC,
    [bldg] ASC,
    [key_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[KeyToBuilding]  WITH CHECK ADD  CONSTRAINT [FK_KeyToBuilding_Key] FOREIGN KEY([owner], [key_id])
REFERENCES [dbo].[Key] ([owner], [key_id])
GO

ALTER TABLE [dbo].[KeyToBuilding] CHECK CONSTRAINT [FK_KeyToBuilding_Key]
GO

ALTER TABLE [dbo].[KeyToBuilding]  WITH CHECK ADD  CONSTRAINT [FK_KeyToBuilding_Bldg] FOREIGN KEY([owner], [bldg])
REFERENCES [dbo].[Bldg] ([owner], [bldg])
GO

ALTER TABLE [dbo].[KeyToBuilding] CHECK CONSTRAINT [FK_KeyToBuilding_Bldg]
GO

每当我尝试设置时,我都会收到错误消息 “表”Key“或”Bldg“中的列与现有主键或UNIQUE约束不匹配。

我是否试图以错误的方式实施这种关系?或做一些蠢事?

该系统用于跟踪人们对不同建筑物的密钥(物理)。这就是为什么有key_id和Key它们不是数据库密钥。

2 个答案:

答案 0 :(得分:2)

这是语法错误的来源;

Bldg表中的主键是:

CONSTRAINT [PK_Bldg] PRIMARY KEY ([bldg], [owner])

KeyToBuilding表格[FK_KeyToBuilding_Bldg]中,您尝试引用([owner], [bldg])而不是([bldg], [owner])

如果您只是简单地清理代码会有所帮助,以下情况可以正常执行:

CREATE TABLE [dbo].[Owners]
  ( 
   [Owner] [varchar](10) NOT NULL
  ,CONSTRAINT [PK_Owners] PRIMARY KEY CLUSTERED ([Owner])
  ) ;

CREATE TABLE [dbo].[Key]
  ( 
   [owner] [varchar](10) NOT NULL
  ,[key_id] [varchar](10) NOT NULL
  ,[description] [varchar](10) NOT NULL
  ,CONSTRAINT [PK_Key] PRIMARY KEY CLUSTERED ([owner], [key_id])
  ) ;
ALTER TABLE [dbo].[Key] ADD  CONSTRAINT [FK_Key_Owners] FOREIGN KEY([owner]) REFERENCES [dbo].[Owners] ([Owner])  ;

CREATE TABLE [dbo].[Bldg]
  ( 
   [bldg] [varchar](10) NOT NULL
  ,[owner] [varchar](10) NOT NULL
  ,CONSTRAINT [PK_Bldg] PRIMARY KEY CLUSTERED ( [bldg], [owner] )
  ) ;
ALTER TABLE [dbo].[Bldg] ADD CONSTRAINT [FK_Bldg_Owners] FOREIGN KEY([owner]) REFERENCES [dbo].[Owners] ([Owner]);

CREATE TABLE [dbo].[KeyToBuilding]
  ( 
   [owner] [varchar](10) NOT NULL
  ,[bldg] [varchar](10) NOT NULL
  ,[key_id] [varchar](10) NOT NULL
  ,CONSTRAINT [PK_KeyToBuilding] PRIMARY KEY CLUSTERED ([owner], [bldg], [key_id])
  );

ALTER TABLE [dbo].[KeyToBuilding] ADD
  CONSTRAINT [FK_KeyToBuilding_Key]  FOREIGN KEY([owner], [key_id]) REFERENCES [dbo].[Key] ([owner], [key_id])
, CONSTRAINT [FK_KeyToBuilding_Bldg] FOREIGN KEY([bldg], [owner])   REFERENCES [dbo].[Bldg] ([bldg], [owner]) ;

现在关于模型 - 我完全不了解它 - 但如果我想跟踪人,钥匙和建筑物,这样做:

alt text

上述模型不会跟踪建筑物所有者,因此会添加BuildingOwner表。

  • 一个人可以拥有几栋建筑物。
  • 建筑物可由几个人(合伙)拥有。

alt text

钥匙也可以拥有所有者,不一定是当前拥有钥匙的人。

  • 钥匙可以打开一幢建筑物,一幢建筑物可以通过许多钥匙打开。
  • 钥匙有所有者。
  • 钥匙由钥匙持有人持有,钥匙持有人可能是也可能不是钥匙的所有人。

alt text

答案 1 :(得分:0)

你应该能够创建它们,你用什么方法来创建给你错误的关系?

可能是你正在向后创建它们。

同时检查表中是否存在冲突数据。在创建FK关系之前,KeyToBuilding中的所有行都需要位于Bldg和Key中。当所有3个表都没有行时,最容易创建关系。