Вторичный индекс в базе данных ключ / значение - PullRequest
0 голосов
/ 04 февраля 2019

Допустим, у меня есть структура данных, такая как

 type User struct {
      UUid string 
      Username string
      Email String 
      Password string 
      FirstName string 
      LastName string
}

Я храню Users [] User в базе данных ключ / значение в levelDB.Уникальный ключ будет UUid, а затем структура пользователя будет наделена и сохранена для этого UUID.

var network bytes.Buffer // Stand-in for a network connection
enc := gob.NewEncoder(&network)
err := enc.Encode(user)
   if err != nil {
      log.Println("Error in encoding gob")
      return "", err
 }
err = dbSession.DBSession.Put([]byte(user.UserID), network.Bytes(), nil)

Поскольку ключ для всех записей является уникальным uuid, я хочу сделать вторичный индекс по электронной почте, чтобычто мне не обязательно сканировать все записи, присутствующие в базе данных, чтобы найти конкретную запись, соответствующую электронной почте.

Что я сделал: я создал ключ с именем SIndex и сохранил карту [строка][string] структура данных в нем, где ключом будет электронная почта, а значением будет uuid.Каждый раз, когда появляется новая запись, этот Sindex будет обновляться для размещения нового uuid и электронной почты.

Это плохой подход: поскольку по мере роста данных всю карту, соответствующую Sindex, нужно извлекать и декодировать, еслиадрес электронной почты не существует, добавьте новый ключ в Sindex, закодируйте его и сохраните снова.

Лучше всего подойдет B-дерево.

Мой вопрос: правильно ли хранить данные вторичного индекса в самой базе данных, если нет, какие стратегии я буду использовать для реализации вторичного индекса, я знаю, что выбор вторичного индекса сильно зависит от данных, но есть ликакие-нибудь хорошие готовые алгоритмы индексации, кроме B-Tree, HashMaps?

1 Ответ

0 голосов
/ 06 февраля 2019

Правильно ли хранить вторичные индексные данные в самой базе данных

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

Еще одна стратегия для повышения производительности, вы можете использовать базы данных в памяти, такие как Redis (или, возможно, сам LevelDB можно использовать для хранения данных в памяти) для хранения вторичного индекса (электронная почта как ключ и UUID как значение).

Существуют ли какие-либо хорошие готовые алгоритмы индексации, кроме B-Tree, HashMaps

В любом случае, B-Tree и HashMap являются структурами данных, а не алгоритмами.И на самом деле вы не индексируете с помощью HashMap, а просто храните HashMaps в качестве значений для вашего ключа.Индексирование обычно зависит от реализации СУБД (мы можем выбирать только из предоставленных ими опций).

Итак, о структурах данных, используемых для индексации, хорошо это или нет, действительно зависит от вариантов использования.Например, если вам нужно выполнить поиск по диапазону, вы можете использовать B-Tree (используемый по умолчанию большинством СУБД), B + Tree (используемый по умолчанию MySQL InnoDB) и Skip List (Redis использует эту структуру данных для своего SortedЗадавать).Подробнее о вторичной индексации с помощью Redis Sorted Set можно прочитать здесь .

А для вашего случая вам нужно только сохранить электронную почту в качестве ключа и UUID в качестве значения.Хеш-таблица обычно используется для этого.Большинство СУБД используют эту структуру данных для доступа к первичному ключу с O (1) сложностью по времени.И я считаю, что реализация LevelDB также основана на этой структуре данных.

...