关于前缀索引问题:局部前置索引如果是唯一索引,为什么必须包括表分区函数中的所有列?
1 个赞
假设一张表按 (city) 列做 HASH 分区,现在要建一个局部唯一索引 UNIQUE(name)(不包含分区键 city):
| 分区 | city | name |
|---|---|---|
| P0 | 北京 | 张三 |
| P1 | 上海 | 张三 |
-
P0 分区的索引只能看到 {name=张三},认为不重复
-
P1 分区的索引也只能看到 {name=张三},也认为不重复
结果:两条 name=张三 的记录都插入成功了,唯一性约束被破坏了,但数据库无法检测到。
这是因为局部索引的唯一性检查是分区内局部检查,无法跨分区验证。
解决方案:唯一索引必须包含所有分区键列
如果唯一索引改为 UNIQUE(name, city),那么:
| 分区 | 索引键 (name, city) |
|---|---|
| P0 | (张三, 北京) |
| P1 | (张三, 上海) |
这两条记录的索引键不同,所以不冲突——这是合理的。
而如果有人试图插入另一条 (name=张三, city=北京) 的记录,由于分区键 city=北京 相同,这条新记录一定会落到 P0 分区,在 P0 的索引中就能检测到重复,从而正确地拒绝插入。
1 个赞
感谢解答