Может ли реляционная база данных использовать способ согласованного хеширования для создания таблицы разделов? - PullRequest
0 голосов
/ 17 августа 2011

Предположим, у нас есть пользовательская таблица, которая должна быть разделена по идентификатору пользователя как целое число 1,2,3 ... n.Могу ли я использовать способ согласованного хеширования, используемый для разбиения таблицы?

Преимущество будет в том случае, если число разделов будет увеличено или уменьшено, старый индекс может быть таким же.

Вопрос A .

Хорошая ли идея использовать согласованный алгоритм хеширования для создания таблицы разделов?

Вопрос B .

Любая реляционная база данных имеет встроенную поддержку?

Я думаю, что некоторые базы данных nosql уже используют ее.

Но база данных здесь относится к реляционной базе данных.

Я только что столкнулся с этим вопросом в интервью.В первой реакции я только что ответил мод по длине, но потом мне будет сложно, если разбить таблицу на несколько частей, это вызовет проблемы.

Ответы [ 2 ]

0 голосов
/ 19 августа 2011

О раздел хэша oracle , часть из справочной документации oracle

После некоторого исследования oracle фактически поддерживает согласованное хеширование по умолчанию для хэширования.Хотя, как это было сделано, пока не опубликовано.Но на самом деле он использует способ HashMap, но скрывает некоторые разделы.Поэтому, когда вы добавляете / удаляете раздел, оракулу очень мало нужно настраивать данные в разных разделах.Алгоритмы обеспечивают только равномерное разбиение данных на разделы с числом чисел, равным 2, например 4. Так что если это не так, то объедините / разделите некоторые разделы.

Магия в том, что если увеличить с четырех разделов до пяти,фактически разбивает один раздел на два.Если уменьшить с четырех разделов на три, он фактически объединяет два раздела в один.

Если у кого-то есть более глубокая проницательность, добавьте более подробный ответ.

Хеш-разделение Хеш-разделение отображает данные в разделы на основе алгоритма хеширования, который Oracle применяет к идентифицируемому вами ключу разделения.Алгоритм хэширования равномерно распределяет строки между разделами, давая разделам примерно одинаковый размер.

Хэш-разбиение является идеальным методом для равномерного распределения данных между устройствами.Хеш-секционирование также является простой в использовании альтернативой секционированию диапазонов, особенно когда данные, подлежащие секционированию, не являются историческими или не имеют явного ключа секционирования.

Примечание:

Вы не можете изменитьАлгоритмы хеширования, используемые при секционировании.

О Хэш-раздел MYSQL , часть из справки mysql doc

Он предоставляет две функции секционирования. Один - это секционирование по HASH.Другой - это разделение по KEY.

Разделение по ключу аналогично разделению по хешу, за исключением того, что, когда разделение хеша использует пользовательское выражение, функция хеширования для разделения ключа предоставляется сервером 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, тогда предыдущий оператор потерпит неудачу.

Но он не говорит, как разделы будут смотреть в коде.

0 голосов
/ 18 августа 2011

После того, как я исследовал некоторые справочные страницы вики, такие как Раздел (база данных)

Я считаю, что моя идея относится к Композитному разбиению .

Составное разбиение допускает определенные комбинации описанных выше схем разбиения, например, сначала применяя разбиение по диапазонам, а затем - хеш-разбиение. Согласованное хэширование можно считать составной частью хэша и разбиения списка, где хеш уменьшает пространство ключей до размера, который можно перечислить.

Также вводятся некоторые понятия, такие как Согласованное хеширование и Хеш-таблица

Но какая-то ссылка, например Раздел (база данных) довольно старая. Если кто-то найдет более свежую ссылку, это будет лучше. Мой ответ действительно неполный. Надеюсь, кто-нибудь ответит лучше!

UPDATE

Похоже, Джонатан Эллис уже упоминал в своем блоге. Распределенная база данных 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);
    }
}
...