假设我们有一个用户表,用户 id 将其分区为整数 1,2,3...n 。我可以使用用于分区表的一致性哈希的方式吗?
好处是,如果分区数量增加或减少,旧索引可以相同。
问题A。
使用一致性哈希算法做分区表是个好主意吗?
问题B。
任何关系数据库都支持这个吗?
我猜一些 nosql 数据库已经在使用它。
但是这里的数据库是指关系数据库。
我刚刚在一次采访中遇到了这个问题。在第一反应中,我只是按长度回答了 mod,但是如果将表划分为更多部分,则会受到挑战,那么它会导致问题。
假设我们有一个用户表,用户 id 将其分区为整数 1,2,3...n 。我可以使用用于分区表的一致性哈希的方式吗?
好处是,如果分区数量增加或减少,旧索引可以相同。
问题A。
使用一致性哈希算法做分区表是个好主意吗?
问题B。
任何关系数据库都支持这个吗?
我猜一些 nosql 数据库已经在使用它。
但是这里的数据库是指关系数据库。
我刚刚在一次采访中遇到了这个问题。在第一反应中,我只是按长度回答了 mod,但是如果将表划分为更多部分,则会受到挑战,那么它会导致问题。
在我研究了一些 wiki 参考页面之后,比如Partition (database)
我相信我的想法属于Composite partitioning。
复合分区允许上述分区方案的某些组合,例如首先应用范围分区,然后应用哈希分区。一致的散列可以被认为是散列和列表分区的组合,其中散列将键空间减少到可以列出的大小。
它还介绍了一些概念,如Consistent hashing和Hash table
但是像分区(数据库)这样的链接有点旧。如果有人能找到更多最新的参考资料会更好。我的回答确实不完整。希望有人能回答得更好!
更新
看起来 Jonathan Ellis 在他的博客中已经提到,Cassandra 分布式数据库现在支持两种分区方案:传统的一致哈希方案和保序分区器。 http://spyced.blogspot.com/2009/05/consistent-hashing-vs-order-preserving.html
来自汤姆怀特的博客。java中一致散列的示例实现
import java.util.Collection;
import java.util.SortedMap;
import java.util.TreeMap;
public class ConsistentHash<T> {
private final HashFunction hashFunction;
private final int numberOfReplicas;
private final SortedMap<Integer, T> circle = new TreeMap<Integer, T>();
public ConsistentHash(HashFunction hashFunction, int numberOfReplicas,
Collection<T> nodes) {
this.hashFunction = hashFunction;
this.numberOfReplicas = numberOfReplicas;
for (T node : nodes) {
add(node);
}
}
public void add(T node) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.put(hashFunction.hash(node.toString() + i), node);
}
}
public void remove(T node) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.remove(hashFunction.hash(node.toString() + i));
}
}
public T get(Object key) {
if (circle.isEmpty()) {
return null;
}
int hash = hashFunction.hash(key);
if (!circle.containsKey(hash)) {
SortedMap<Integer, T> tailMap = circle.tailMap(hash);
hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
}
return circle.get(hash);
}
}
关于oracle 哈希分区,部分来自 oracle 帮助文档
经过一番研究,oracle 实际上确实通过默认哈希分区支持一致性哈希。虽然它是如何做到的是一个秘密,没有公布。但它实际上利用了HashMap的方式,只是隐藏了一些分区。因此,当您添加/删除分区时,oracle 调整不同分区中的数据的工作非常少。该算法仅确保将数据均匀地拆分为 2 的数字幂的分区,例如 4。因此,如果不是,则合并/拆分一些分区。
魔术就像从四个分区增加到五个分区,实际上是将一个分区拆分为两个分区。如果从四个分区减少到三个,实际上是将两个分区合并为一个。
如果有人有更多见解,请添加更详细的答案。
散列分区 散列分区根据 Oracle 应用于您标识的分区键的散列算法将数据映射到分区。散列算法在分区之间均匀分布行,使分区大小大致相同。
哈希分区是跨设备均匀分布数据的理想方法。哈希分区也是范围分区的一种易于使用的替代方案,尤其是当要分区的数据不是历史数据或没有明显的分区键时。
笔记:
您不能更改分区使用的散列算法。
关于MYSQL 哈希分区,部分来自 mysql 帮助文档
它提供了两种分区功能一种是HASH分区。另一种是KEY分区。
key 分区类似于 hash 分区,除了 hash 分区使用用户定义的表达式,key 分区的 hash 函数由 MySQL 服务器提供。MySQL Cluster为此使用MD5() ;对于使用其他存储引擎的表,服务器使用自己的内部散列函数,该函数基于与PASSWORD()相同的算法。CREATE TABLE ... PARTITION BY KEY 的语法规则类似于创建按哈希分区的表的语法规则。
主要区别如下:
• 使用KEY 而不是HASH。
•KEY 只接受一个或多个列名的列表。从 MySQL 5.1.5 开始,用作分区键的列必须包含表的部分或全部主键,如果表有一个。
CREATE TABLE k1 (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20)
)
PARTITION BY KEY()
PARTITIONS 2;
如果没有主键但有唯一键,则唯一键用于分区键:
CREATE TABLE k1 (
id INT NOT NULL,
name VARCHAR(20),
UNIQUE KEY (id)
)
PARTITION BY KEY()
PARTITIONS 2;
但是,如果唯一键列未定义为 NOT NULL,则前面的语句将失败。
但它不告诉它如何分区,将不得不查看代码。