【问题标题】:How can i make one clustered index on two columns in a table如何在表中的两列上创建一个聚集索引
【发布时间】:2020-01-01 14:41:46
【问题描述】:

我有这张桌子

UserProgrammingLanguagesId
UserId,
Name,
ProgrammingLanguageId,
KnowledgeId.

我正在插入属于 FK-PK 关系的 ProgrammingLanguageId 和 KnowledgeId 值。但我不想要,例如,如果一个用户有 ProgrammingLanguageId - 1(Java Script),他的知识是 KnowledgeId - 2 (中级),在该表中具有相同的值。我想在某些用户有 1 和 2 个值时进行设置,以防止重复,因为一个用户可以通过一个知识 id 知道一种编程语言,而不是两个和反向。

这是上传的表格截图 https://ibb.co/sPn5zT7

//i am preventing this and it is working
insert into userPLs values(5,'9d313e61-8fb7-4011-88f0-6494621f43f7','Doe',1,1)

//How can i prevent this insert here?
insert into userPLs values(5,'9d313e61-8fb7-4011-88f0-6494621f43f7','Doe',1,2)


【问题讨论】:

  • ibb.co/sPn5zT7 这是桌子先生
  • 简而言之:您希望用户只能为每种编程语言指定 一个 知识级别?你需要一个对UserId, ProgrammingLanguageId 的唯一约束。在这种情况下,KnowledgeId 与其属性无关
  • 我不明白为什么Doe,2,1 会是无效的,(有人可能是许多语言的初学者)但如果是这样,只需在UserId,KnowledgeId 上创建一个唯一约束即可。跨度>
  • 一名员工不应该掌握一种语言的基础和中级,我该怎么做?
  • 请更新您的问题以反映这一点。鉴于表结构,您的要求转化为“每个用户只能指定一种语言”,这转化为 UserId, ProgrammingLanguageId 的唯一约束,就像我已经说过的那样

标签: sql sql-server database-indexes


【解决方案1】:

这有两种方法,具体取决于数据库。

一种是强制对两个值进行排序,然后有一个唯一的约束:

alter table userPLs add constraint chk_userPLS_ids
    check (ProgrammingLanguageId < KnowledgeId);

alter table userPLs add constraint unq_userPLS_ids
    unique (ProgrammingLanguageId, KnowledgeId);

这将只允许您插入 (1, 2),而不是 (2, 1),因此您无法获得重复项。

第二种方法是对唯一索引使用least()/greatest()或类似逻辑:

create unique index unq_userPLS_ids on
    userPLs ( least(ProgrammingLanguageId, KnowledgeId),
             greatest(ProgrammingLanguageId, KnowledgeId),
           );

并非所有数据库都支持least()greatest(),但它们是大多数数据库中的常用功能。一些数据库不支持基于函数的索引,但通常有一种变通方法。

在 SQL Server 中,您需要使用计算列和case 表达式:

alter table userPLs add column least_pkid as (ProgrammingLanguageId

alter table userPLs 添加列 great_pkid 为 (ProgrammingLanguageId > KnowledgeId 时的情况 然后 ProgrammingLanguageId 否则 KnowledgeId end) 持久化;

create unique index unq_userPLS_ids on
    userPLs ( least_pk, greatest_pk );

我应该补充一点,您也可以为此目的定义触发器,但这不是必需的。

【讨论】:

  • 感谢您的回复 Gordon。我试试这个create unique index unq_userPLS_ids on create unique index unq_userPLS_ids on userPLs (least(ProgrammingLanguageId, KnowledgeId) best(ProgrammingLanguageId, KnowledgeId) ) 附近的语法不正确,但我删除了所有,除了在方法内部。顺便说一句,我使用的是 MS SQL
猜你喜欢
  • 1970-01-01
  • 2012-12-11
  • 2014-02-23
  • 2011-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-26
  • 2020-02-16
相关资源
最近更新 更多