我是分区的新手。不知道它的存在,但当我尝试使我们的新'url_hash'
列在数据库中的表中唯一时,才意识到。并收到错误消息:
唯一索引必须包含表分区函数中的所有列
这是一个由另一个我不认识的人创建的数据库,他们不再参与该项目。
我试图阅读mysql文档并在论坛上阅读有关分区的内容。它是什么以及它是如何工作的。了解目的,将表"划分"为几个"部分",以便更快地检索相关数据。一个常见的例子是按年间隔进行分区。但大多数示例都显示了手动方法。例如,您决定少于三年的特定年份。例如:
PARTITION BY RANGE ( YEAR(separated) ) (
PARTITION p0 VALUES LESS THAN (1991),
PARTITION p1 VALUES LESS THAN (1996),
PARTITION p2 VALUES LESS THAN (2001),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
但是在我们的表中,分区是这样创建的:
PARTITION BY HASH ( `feeditemsID` + YEAR(`feeddate`))
PARTITIONS 3;
那是什么意思?我们的分区如何工作?
feeditemsID
是表中每一行的唯一 ID。
使用哈希分区时,包含每条记录的分区是通过从表达式 feaditemsID + YEAR(feeddate)
计算哈希代码,然后通过分区数找到此代码的模数来确定的。所以如果一行的哈希码是123,它计算123 % 3
,这是0
,所以记录进入分区0
。
这在MySQL文档中进行了解释。
如前所述,
注意
如果要分区的表具有 UNIQUE 键,则作为参数提供给 HASH 用户函数或 KEY column_list的任何列都必须是该键的一部分。
在您的情况下,表的主键需要为:
PRIMARY KEY (feeditemsID, feeddate)
假设feeditemsID
已经是唯一的(大概它是一个自动增量列),就保持数据唯一而言,向主列添加feeddate
是多余的,但它需要满足分区要求。将组合键中的feeditemsID
放在首位将允许它单独用于优化表查找。
此要求可能是因为每个分区都有自己的索引。插入/更新行并检查唯一性时,它只检查将存储该行的分区的索引。因此,当它使用哈希函数找到分区时,它需要确保此分区将唯一包含索引列。
有关更多信息,请参阅
分区键、主键和唯一键