2

假设我们有一个用户表,用户 id 将其分区为整数 1,2,3...n 。我可以使用用于分区表的一致性哈希的方式吗?

好处是,如果分区数量增加或减少,旧索引可以相同。

问题A。

使用一致性哈希算法做分区表是个好主意吗?

问题B。

任何关系数据库都支持这个吗?

我猜一些 nosql 数据库已经在使用它。

但是这里的数据库是指关系数据库。

我刚刚在一次采访中遇到了这个问题。在第一反应中,我只是按长度回答了 mod,但是如果将表划分为更多部分,则会受到挑战,那么它会导致问题。

4

2 回答 2

0

在我研究了一些 wiki 参考页面之后,比如Partition (database)

我相信我的想法属于Composite partitioning

复合分区允许上述分区方案的某些组合,例如首先应用范围分区,然后应用哈希分区。一致的散列可以被认为是散列和列表分区的组合,其中散列将键空间减少到可以列出的大小。

它还介绍了一些概念,如Consistent hashingHash 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);
    }
}
于 2011-08-18T04:27:17.573 回答
0

关于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,则前面的语句将失败。

但它不告诉它如何分区,将不得不查看代码。

于 2011-08-19T08:24:39.540 回答