我正在尝试在多个表之间创建一个唯一约束。我在这里找到了类似的问题,但它们并没有完全捕捉到我要做的事情的精髓。
例如,我有三个表,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,
[ItemName] [nvarchar](32) NOT NULL,
[Value] [bit] NOT NULL,
CONSTRAINT [uc_t_Discrete] UNIQUE(AppName, ItemName)
)
CREATE TABLE t_Message(
[AppName] [nvarchar](20) NOT NULL,
[ItemName] [nvarchar](32) NOT NULL,
[Value] [nvarchar](256) NOT NULL,
CONSTRAINT [uc_t_Message] UNIQUE(AppName, ItemName)
)
我的目标是使AppName和ItemName在所有3个表中都保持唯一。例如,在应用程序X中,项目名称为Y的内容不能同时存在于模拟和离散表中。
请注意,这个例子是人为的,每种类型的实际数据都不同且足够大,以至于将表合并并添加类型列相当麻烦。
如果您有任何关于此方法的建议,我很乐意听取!
---- 开始编辑 2012-04-26 13:28 CST ----
谢谢大家的答复!
看起来可能需要修改数据库的架构,这没问题。
将表合并到单个表中并不是一个可行的选项,因为每种类型都有大约30个不匹配的列(不幸的是,修改这些列不是一个选项)。 这可能导致每行中存在大量未使用的列,这似乎是一个糟糕的想法。
像John Sikora和其他人所提到的添加第4个表可能是一个选项,但我想先验证一下。
修改架构如下:
CREATE TABLE t_AllItems(
[id] [bigint] IDENTITY(1,1) NOT NULL,
[itemType] [int] NOT NULL,
[AppName] [nvarchar](20) NOT NULL,
[ItemName] [nvarchar](32) 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,
[Value] [float] NOT NULL,
FOREIGN KEY (itemId) REFERENCES t_AllItems(id)
)
CREATE TABLE t_Discrete(
[itemId] [bigint] NOT NULL,
[Value] [bit] NOT NULL,
FOREIGN KEY (itemId) REFERENCES t_AllItems(id)
)
CREATE TABLE t_Message(
[itemId] [bigint] NOT NULL,
[Value] [nvarchar](256) NOT NULL,
FOREIGN KEY (itemId) REFERENCES t_AllItems(id)
)
关于这种方法,我只有一个问题。这是否在子表中强制执行唯一性?
例如,是否可能存在一个名为“Item”的项目,其具有'id' 9,其中t_Analog具有'itemId'为9且'value'为9.3,同时t_Message也具有'itemId' 9和'value'为"foo"?
我可能没有完全理解这种额外的表格方法,但我不反对它。
如果我理解有误,请纠正我。