关系型数据库能否利用一致性哈希的方式进行分区表?

3
假设我们有一个用户表,通过用户id作为整数1,2,3...n进行分区。我可以使用用于分割表的一致性哈希方法吗?
好处在于,如果分区的数量增加或减少,旧索引仍可保持不变。
问题A。
使用一致性哈希算法来分割表是个好主意吗?
问题B。
是否有任何关系型数据库内置支持此功能?
我猜已经有一些NoSQL数据库在使用它。
但这里的数据库是指关系型数据库。
我在面试中遇到了这个问题。我的第一反应是将其模长取余,但后来被质疑如果将表分成更多块,则会导致问题。
2个回答

0

我研究了一些维基参考页面,例如Partition (database)

我认为我的想法属于组合分区

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

它还介绍了一些概念,如一致性哈希哈希表

但像Partition (database)这样的链接有点过时了。如果有人能找到更新的参考资料,那就更好了。我的回答确实不完整。希望有人能回答得更好!

更新

看起来Jonathan Ellis在他的博客中已经提到,Cassandra分布式数据库现在支持两种分区方案:传统的一致性哈希方案和有序分区器。 http://spyced.blogspot.com/2009/05/consistent-hashing-vs-order-preserving.html

来自Tom White的博客。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);
    }
}

0
关于Oracle哈希分区,这是来自Oracle帮助文档的一部分。
经过一些研究,Oracle实际上支持默认哈希分区的一致性哈希。虽然它是如何做到的是一个秘密并且没有公开。但它实际上利用了HashMap的方式,但隐藏了一些分区。因此,当您添加/删除分区时,Oracle需要调整不同分区中的数据的工作量非常少。该算法仅确保将数据均匀地分割为2的幂次方(例如4)的分区。因此,如果不是,则合并/拆分一些分区。
神奇的是,如果要从四个分区增加到五个分区,它实际上会将一个分区分成两个。如果要从四个分区减少到三个分区,它实际上会将两个分区合并成一个。
如果有人有更深入的见解,请提供更详细的答案。
哈希分区 哈希分区根据Oracle应用于您标识的分区键的哈希算法将数据映射到分区。哈希算法平均分配行到分区中,使分区大小大致相同。
哈希分区是在设备之间均匀分布数据的理想方法。哈希分区也是范围分区的易于使用的替代方法,特别是当要分区的数据不是历史数据或没有明显的分区键时。
注意:
您无法更改分区使用的哈希算法。
关于MYSQL哈希分区,来自mysql帮助文档的一部分。
它提供了两个分区函数。一个是哈希分区,另一个是按键分区。
按键分区类似于哈希分区,不同之处在于哈希分区使用用户定义的表达式,而按键分区的哈希函数由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,则上述语句将失败。

但它并没有说明如何进行分区,需要查看代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接