我有一个应用程序,用户可以在其中创建自己的自定义私人标签,但也有一些固定的系统范围的通用标签。标签存储在数据库表中,其中通用标签是USER_ID
为NULL
的那些标签。为包括全局用户在内的每个用户实施独特价值
CREATE TABLE TAG (
TAG_ID INT IDENTITY(1, 1) NOT NULL,
TAG_NAME VARCHAR(40) NOT NULL,
USER_ID INT,
CONSTRAINT TAG_PK PRIMARY KEY (TAG_ID),
CONSTRAINT TAG_FK1 FOREIGN KEY (USER_ID)
REFERENCES [USER] (USER_ID)
);
CREATE INDEX TAG_IDX1 ON TAG (USER_ID);
我想在数据库级别的标签是唯一的每个用户强制执行,是什么意思是说:
用户可能仅具有给出名称的标签,但其他客户也可以有他们自己的标签这样的名字。
常见标签也应该计算在内,因此用户不能创建已经很常见的标签。
这样一个简单的索引将无法正常工作,因为它只能防止群体中受骗者(普通标签的每个用户) - 它仍然有可能作为用户标签重新创建常用标记:
CREATE UNIQUE INDEX TAG_UK1 ON TAG (TAG_NAME, USER_ID);
我相信,SQL Server不允许在索引表达式,如:
-- Incorrect syntax near the keyword 'COALESCE'.
CREATE UNIQUE INDEX TAG_UK1 ON TAG (TAG_NAME, COALESCE(USER_ID, 'COMMON'));
你能想出一些其他的办法?
听起来像你需要重新考虑一下架构。这是一种多对多的关系(有一些额外的注意事项),几乎不可能只用两个表。 –
在这种情况下,通过索引保证唯一性可能无法实现-AFAIK,无论如何,听起来你也会因为性能原因利用索引。你为什么不把这个检查放在存储过程或触发器中? – Icarus
@SeanLange我没有这样想过,从数据库设计的角度来看是有道理的。但考虑到我可能还需要编辑管理工具和代码库的许多其他部分,也许最好是允许模糊并调整UI以单独显示它们 - 这对我的精确用例可能是可以接受的。 –