微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – 跨多个表的SQL唯一约束

我试图在多个表之间创建一个唯一约束。我在这里找到了类似的问题,但是他们并没有完全捕捉到我想要做的精神。

举个例子,我有三个表,t_Analog,t_discrete,t_Message

CREATE TABLE t_Analog(
    [AppName] [nvarchar](20) NOT NULL,[ItemName] [nvarchar](32) NOT NULL,[Value] [float] NOT NULL,CONSTRAINT [uc_t_Analog] UNIQUE(AppName,ItemName)
)

CREATE TABLE t_discrete(
    [AppName] [nvarchar](20) NOT NULL,[Value] [bit] NOT NULL,CONSTRAINT [uc_t_discrete] UNIQUE(AppName,ItemName)
)

CREATE TABLE t_Message(
    [AppName] [nvarchar](20) NOT NULL,[Value] [nvarchar](256) NOT NULL,CONSTRAINT [uc_t_Message] UNIQUE(AppName,ItemName)
)

我的目标是在所有3个表中使AppName和ItemName唯一。例如,应用程序X中的项目名称Y不能同时存在于模拟和离散表中。

请注意,这个例子是设计的,每个Type的实际数据是不同的,大到足以组合表并添加一个非常难看的Type列。

如果您对此方法有任何建议,我很乐意听到它们!

—-开始编辑2012-04-26 13:28 CST —-

谢谢大家的答案!

似乎可能有理由修改数据库的架构,这很好。

将表组合到单个表中实际上并不是一个可行的选项,因为每个类型的列数大约为30列(不幸的是,修改这些列不是一个选项)。这可能导致每行中没有使用大部分列,这似乎是一个坏主意。

添加第4个表,如John Sikora和其他人提到的,可能是一个选项,但我想首先验证这一点。

修改架构为:

CREATE TABLE t_AllItems(
    [id] [bigint] IDENTITY(1,1) NOT NULL,[itemType] [int] NOT NULL,[AppName] [nvarchar](20) NOT NULL,CONSTRAINT [pk_t_AllItems] PRIMARY KEY CLUSTERED ( [id] )
    CONSTRAINT [uc_t_AllItems] UNIQUE([id],[AppName],[ItemName])
) ON [PRIMARY]

CREATE TABLE t_Analog(
    [itemId] [bigint] NOT NULL,FOREIGN KEY (itemId) REFERENCES t_AllItems(id)
)

CREATE TABLE t_discrete(
    [itemId] [bigint] NOT NULL,FOREIGN KEY (itemId) REFERENCES t_AllItems(id)
)

CREATE TABLE t_Message(
    [itemId] [bigint] NOT NULL,FOREIGN KEY (itemId) REFERENCES t_AllItems(id)
)

关于这种方法,我只有一个问题。这是否会强制子表中的唯一性?

例如,是否存在“项目”,其中“id”9表格为t_Analog,其中“itemId”为9,“value”为9.3,同时t_Message的“itemId”为9,其中“value”为“富”?

我可能不完全理解这种额外的表格方法,但我并不反对

如果我错了,请纠正我。

解决方法

添加第4个表专门针对您想要唯一的值,然后使用一对多关系将这些键从此表链接到其他键。
例如,您将拥有一个唯一的表,其中包含ID,AppName和ItemName以构成其3列。然后将此表链接到其他人。

如何做到这一点就是一个很好的例子
Create a one to many relationship using SQL Server

编辑:这是我会做的,但考虑到您的服务器需求,您可以更改所需的内容

CREATE TABLE AllItems(
    [id] [int] IDENTITY(1,CONSTRAINT [pk_AllItems] PRIMARY KEY CLUSTERED ( [id] ASC )
) ON [PRIMARY]

CREATE TABLE Analog(
    [itemId] [int] NOT NULL,[Value] [float] NOT NULL
)

CREATE TABLE discrete(
    [itemId] [int] NOT NULL,[Value] [bit] NOT NULL
)

CREATE TABLE Message(
    [itemId] [bigint] NOT NULL,[Value] [nvarchar](256) NOT NULL
)

ALTER TABLE [Analog] WITH CHECK 
    ADD CONSTRAINT [FK_Analog_AllItems] FOREIGN KEY([itemId])
REFERENCES [AllItems] ([id])
GO
ALTER TABLE [Analog] CHECK CONSTRAINT [FK_Analog_AllItems]
GO

ALTER TABLE [discrete] WITH CHECK 
    ADD CONSTRAINT [FK_discrete_AllItems] FOREIGN KEY([itemId])
REFERENCES [AllItems] ([id])
GO
ALTER TABLE [discrete] CHECK CONSTRAINT [FK_discrete_AllItems]
GO

ALTER TABLE [Message] WITH CHECK 
    ADD CONSTRAINT [FK_Message_AllItems] FOREIGN KEY([itemId])
REFERENCES [AllItems] ([id])
GO
ALTER TABLE [Message] CHECK CONSTRAINT [FK_Message_AllItems]
GO

从我可以告诉你的语法很好,我只是简单地改变它,因为我更熟悉它,但要么应该工作。

原文地址:https://www.jb51.cc/mssql/84422.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐