【发布时间】:2012-05-07 10:52:02
【问题描述】:
我正在尝试跨多个表创建唯一约束。我发现这里回答了类似的问题,但它们并没有完全抓住我想要做的事情的精神。
例如,我有三个表,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 不能同时存在于模拟表和离散表中。
请注意,此示例是人为设计的,每个 Type 的实际数据不同且大到足以使组合表和添加 Type 列变得非常难看。
如果您对此方法有任何建议,我很乐意听取他们的意见!
---- BEGIN EDIT 2012-04-26 13:28 CST ----
谢谢大家的回答!
看来可能需要修改这个数据库的架构,没关系。
将这些表组合成一个表并不是一个真正可行的选择,因为每种类型大约有 30 列不匹配(遗憾的是,修改这些列不是一种选择)。这可能会导致每一行中没有使用大部分列,这似乎是个坏主意。
像 John Sikora 和其他人提到的那样,添加第四张桌子可能是一种选择,但我想先验证一下。
将架构修改为:
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)
)
我对这种方法只有一个问题。这会在子表中强制执行唯一性吗?
例如,是否不存在具有 'id' 9 的 'Item' 表 t_Analog 的 'itemId' 为 9 和 'value' 为 9.3,同时 t_Message 的 'itemId' 为 9 和 ' “foo”的值?
我可能不完全理解这种额外的表格方法,但我并不反对。
如果我在这方面错了,请纠正我。
【问题讨论】:
-
您在正确的轨道上,但完整性约束还不够好。例如,ID 号 100 可能出现在每个表中。要更严格地使用项目类型,请参阅 this answer 和 this answer。
-
这不是一个约束,但你可以使用 CREATE SEQUENCE 来获取一个唯一的数字来放入每条记录:docs.microsoft.com/en-us/sql/t-sql/statements/… 我认为这个功能是在 2012 版中添加的。
标签: sql-server database-design unique-constraint