【发布时间】:2014-03-14 19:16:10
【问题描述】:
我目前正在设计一个要在 SQL Server 中实现的数据库。我毫无问题地创建了以下表格:
CREATE TABLE [Client] (
[ClientId] INT NOT NULL,
[Name] VARCHAR(45) NOT NULL,
[IsEnabled] BIT NOT NULL DEFAULT 1,
CONSTRAINT PK_TCASystem PRIMARY KEY CLUSTERED (
ClientId
)
);
CREATE TABLE [Configuration] (
[ConfigId] INT NOT NULL,
[ClientId] INT NOT NULL,
[Name] VARCHAR(45) NOT NULL,
CONSTRAINT PK_Configuration PRIMARY KEY CLUSTERED (
ConfigId, ClientId
),
CONSTRAINT "FK_SystemConfiguration" FOREIGN KEY
(
ClientId
) REFERENCES [Client] (
ClientId
)
);
但是,当我尝试添加这个时:
CREATE TABLE [Mail] (
[MailId] INT NOT NULL,
[ConfigId] INT NOT NULL,
[Recipient] VARCHAR(500) NOT NULL,
[Sender] VARCHAR(50) NOT NULL,
[Subject] VARCHAR(250) NOT NULL,
[Message] TEXT NULL,
CONSTRAINT PK_Mail PRIMARY KEY CLUSTERED (
MailId, ConfigId
),
CONSTRAINT "FK_ConfigurationMail" FOREIGN KEY
(
ConfigId
) REFERENCES [Configuration] (
ConfigId
)
);
我收到一条错误消息,提示 There are no primary or candidate keys in the referenced table 'Configuration' that match the referencing column list in the foreign key 'FK_ConfigurationMail'。我相信这是因为约束试图引用ConfigId,只有一半的复合键,为此我还需要引用ClientId,对吗?
但我的问题是我首先在 MYSQL Workbench 中为这个数据库做设计,在那里我指出 Configuration 和 Mail 以及 Client and Configuration 具有 1:n 识别关系(因为如果首先没有Configuration 实例,则无法创建Mail 实例,同时如果没有首先分配给Client 实例,则Configuration 实例不能存在),因此它创建了复合Configuration 和 Mail 的密钥。你可以看到那个here的图片。
所以我的问题是,如何将这种识别关系转换为 SQL Server?还是不可能?
编辑:按照建议,我将从Configuration 表中删除复合键,尽管我的问题仍然存在:如果我有一个 1:n 识别关系,其中一个表涉及使用复合键,我如何在 SQL Server 上显示? 或者这种情况不应该发生?
第二次编辑:对于任何可能遇到此问题的人,this 的帖子非常值得一读。解决了我在这件事上的所有困惑。
【问题讨论】:
-
让我看看我是否明白。如果没有将first分配给客户端,配置实例就无法存在??
-
没错。更改措辞以防它过于模棱两可。
-
另外,你的设计应该有一个
Client表(ClientId单独作为主键),一个Configuration表(ConfigurationId单独作为主键),和一个关联它们的ClientConfiguration表(ClientId, ConfigurationId作为复合主键) -
您的模型很好,只需删除复合键即可。仅当您需要多个客户端的相同配置时才需要
ClientConfiguration。 -
您当前的意思是
Configuration表可能有多个相同的ConfigurationId值(因为它有一个复合主键)。在 SQL Server 中(每个 RBDMS 都应该是这种方式,不知道为什么 MySQL 允许),你不能引用主键的一部分,它需要引用整个主键
标签: sql sql-server-2008 foreign-keys primary-key foreign-key-relationship