Что такое первичный ключ хэша и диапазона?

220

Я не могу понять, что первичный ключ Range здесь -

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#WorkingWithTables.primary.key

и как это работает?

Что они подразумевают под «неупорядоченным индексом хеш-функции в атрибуте хэш-функции и индексом отсортированного диапазона в атрибуте диапазона»?

Манна
источник

Ответы:

572

« Первичный ключ хеширования и диапазона » означает, что одна строка в DynamoDB имеет уникальный первичный ключ, состоящий из хеша и ключа диапазона . Например, с хэш-ключом X и ключом диапазона Y , ваш первичный ключ - это XY . Вы также можете иметь несколько ключей диапазона для одной и той же хэш-клавиши, но комбинация должна быть уникальной, как XZ и XA . Давайте использовать их примеры для каждого типа таблицы:

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

Это означает, что каждая строка отключена от этого значения. Каждая строка в DynamoDB будет иметь обязательное уникальное значение для этого атрибута . Неупорядоченный хэш-индекс означает то, что говорит - данные не упорядочены, и вам не дают никаких гарантий того, как эти данные хранятся. Вы не сможете выполнять запросы по неупорядоченному индексу, например, « Получить мне все строки, у которых ProductID больше X» . Вы пишете и выбираете элементы на основе хэш-ключа. Например, возьмимня строка из этой таблицы , которая имеет ProductID X . Вы делаете запрос по неупорядоченному индексу, так что вы получаете против него, в основном, поиск по значению ключа, очень быстрый и с очень низкой пропускной способностью.


Первичный ключ хэша и диапазона - первичный ключ состоит из двух атрибутов. Первый атрибут - это атрибут hash, а второй - атрибут range. Например, таблица темы форума может иметь ForumName и Subject в качестве первичного ключа, где ForumName - это атрибут хеша, а Subject - атрибут диапазона. DynamoDB строит неупорядоченный хеш-индекс по атрибуту хеш-функции и отсортированный индекс диапазона по атрибуту диапазона.

Это означает, что первичный ключ каждой строки представляет собой комбинацию ключа хеша и диапазона . Вы можете делать прямые попадания в отдельные строки, если у вас есть и хеш, и ключ диапазона, или вы можете сделать запрос по отсортированному индексу диапазона . Например, получить Получить все строки из таблицы с хэш-ключом X, у которых ключи диапазона больше Y , или другие запросы, влияющие на это. Они имеют лучшую производительность и меньшее использование емкости по сравнению с сканированиями и запросами к полям, которые не проиндексированы. Из их документации :

Результаты запроса всегда сортируются по ключу диапазона. Если тип данных ключа диапазона - Number, результаты возвращаются в числовом порядке; в противном случае результаты возвращаются в порядке значений кодов символов ASCII. По умолчанию порядок сортировки возрастает. Чтобы изменить порядок, установите для параметра ScanIndexForward значение false

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

mkobit
источник
54
это один из самых полезных ответов о переполнении стека, которые я когда-либо читал.
Томми,
7
Почему нет возможности использовать диапазон без хеша? Например, если все мои данные хранятся с меткой времени в качестве первичного ключа, я бы хотел иметь возможность выбрать «все данные между 14 и 16 часами дня 15.10.2015»
Teofrostus
3
@Teofrostus, ключ хеша используется для идентификации раздела, который содержит элемент (ы). Без этого DynamoDB не смог бы определить, в каком разделе искать. Не зная, где искать, побеждает Query, и это вариант использования для сканирования (или Global Secondary Index, но это не подходит для вашего случая использования ничего, кроме времени). ряд для выбора данных).
Шелдон
1
@mkobit, есть ли способ получить все ключи сортировки, заданные ключом раздела, без сканирования?
unknownerror
1
@VNR Я не уверен, что понимаю ваш вопрос в контексте DynamoDB. Вы хотите получить все ключи диапазона хэш + при предоставлении ключа хеша?
mkobit
19

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

Только способ получить строку осуществляется с помощью первичного ключа

getRow(pk: PrimaryKey): Row

Структура данных первичного ключа может быть такой:

// If you decide your primary key is just the partition key.
class PrimaryKey(partitionKey: String)

// and in thids case
getRow(somePartitionKey): Row

Однако вы можете решить, что ваш первичный ключ - это ключ раздела + ключ сортировки в этом случае:

// if you decide your primary key is partition key + sort key
class PrimaryKey(partitionKey: String, sortKey: String)

getRow(partitionKey, sortKey): Row
getMultipleRows(partitionKey): Row[]

Итак, суть:

  1. Решили, что ваш первичный ключ - это только ключ раздела? получить одну строку по ключу раздела.

  2. Решили, что вашим первичным ключом является ключ раздела + ключ сортировки? 2.1 Получить одну строку (ключ разделения, ключ сортировки) или получить диапазон строк (ключ разделения)

В любом случае вы получаете одну строку по первичному ключу, единственный вопрос - если вы определили, что первичный ключ должен быть только ключом раздела или ключом раздела + ключом сортировки

Строительные блоки:

  1. Стол
  2. Пункт
  3. KV Атрибут.

Думайте об Предмете как о строке, а об атрибуте КВ - как о клетках в этом ряду.

  1. Вы можете получить элемент (строку) по первичному ключу.
  2. Вы можете получить несколько элементов (несколько строк), указав (HashKey, RangeKeyQuery)

Вы можете сделать (2), только если вы решили, что ваш ПК состоит из (HashKey, SortKey).

Более наглядно, как это сложно, как я это вижу:

+----------------------------------------------------------------------------------+
|Table                                                                             |
|+------------------------------------------------------------------------------+  |
||Item                                                                          |  |
||+-----------+ +-----------+ +-----------+ +-----------+                       |  |
|||primaryKey | |kv attr    | |kv attr ...| |kv attr ...|                       |  |
||+-----------+ +-----------+ +-----------+ +-----------+                       |  |
|+------------------------------------------------------------------------------+  |
|+------------------------------------------------------------------------------+  |
||Item                                                                          |  |
||+-----------+ +-----------+ +-----------+ +-----------+ +-----------+         |  |
|||primaryKey | |kv attr    | |kv attr ...| |kv attr ...| |kv attr ...|         |  |
||+-----------+ +-----------+ +-----------+ +-----------+ +-----------+         |  |
|+------------------------------------------------------------------------------+  |
|                                                                                  |
+----------------------------------------------------------------------------------+

+----------------------------------------------------------------------------------+
|1. Always get item by PrimaryKey                                                  |
|2. PK is (Hash,RangeKey), great get MULTIPLE Items by Hash, filter/sort by range     |
|3. PK is HashKey: just get a SINGLE ITEM by hashKey                               |
|                                                      +--------------------------+|
|                                 +---------------+    |getByPK => getBy(1        ||
|                 +-----------+ +>|(HashKey,Range)|--->|hashKey, > < or startWith ||
|              +->|Composite  |-+ +---------------+    |of rangeKeys)             ||
|              |  +-----------+                        +--------------------------+|
|+-----------+ |                                                                   |
||PrimaryKey |-+                                                                   |
|+-----------+ |                                       +--------------------------+|
|              |  +-----------+   +---------------+    |getByPK => get by specific||
|              +->|HashType   |-->|get one item   |--->|hashKey                   ||
|                 +-----------+   +---------------+    |                          ||
|                                                      +--------------------------+|
+----------------------------------------------------------------------------------+

Итак, что происходит выше. Обратите внимание на следующие наблюдения. Как мы уже говорили, наши данные принадлежат (Table, Item, KVAttribute). Тогда у каждого предмета есть первичный ключ. Теперь то, как вы составляете этот первичный ключ, имеет смысл для доступа к данным.

Если вы решите, что ваш PrimaryKey - это просто хеш-ключ, тогда прекрасно, что вы можете получить из него один элемент. Однако если вы решите, что вашим первичным ключом является hashKey + SortKey, то вы также можете выполнить запрос диапазона по первичному ключу, потому что вы получите свои элементы по (HashKey + SomeRangeFunction (на ключе диапазона)). Таким образом, вы можете получить несколько элементов с помощью запроса первичного ключа.

Примечание: я не ссылался на вторичные индексы.

Томер Бен Дэвид
источник
4

Хорошо объясненный ответ уже дан @mkobit, но я добавлю большую картину ключа диапазона и ключа хеша.

Одним словом range + hash key = composite primary key CoreComponents Динамодб введите описание изображения здесь

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

Таким образом, оба имеют разные цели и вместе помогают выполнять сложные запросы. В приведенном выше примере hashkey1 can have multiple n-range.Другим примером диапазона и хэш-ключа является игра, пользователь A (hashkey)может играть в Ngame(range)

введите описание изображения здесь

Таблица Music, описанная в таблицах, элементах и ​​атрибутах, является примером таблицы с составным первичным ключом (Artist и SongTitle). Вы можете получить доступ к любому элементу в таблице «Музыка» напрямую, если вы укажете значения Artist и SongTitle для этого элемента.

Составной первичный ключ дает вам дополнительную гибкость при запросе данных. Например, если вы предоставляете только значение для Artist, DynamoDB извлекает все песни этого исполнителя. Чтобы получить только подмножество песен определенного исполнителя, вы можете указать значение для Artist вместе с диапазоном значений для SongTitle.

введите описание изображения здесь

https://www.slideshare.net/InfoQ/amazon-dynamodb-design-patterns-best-practices https://www.slideshare.net/AmazonWebServices/awsome-day-2016-module-4-databases-amazon-dynamodb -and-amazon-rds https://ceyhunozgun.blogspot.com/2017/04/implementing-object-persistence-with-dynamodb.html

Adiii
источник
В примере с Musicтаблицей один исполнитель не может создать две песни с одинаковым названием, но это удивительно - в видеоиграх у нас есть Doom 1993 года и Doom 2016 года en.wikipedia.org/wiki/Doom_(franchise) с одним и тем же «исполнителем» ( разработчик): id Software.
Виталий Зданевич
0

@vnr вы можете получить все ключи сортировки, связанные с ключом раздела, просто используя запрос с ключом разделения. Нет необходимости в сканировании. Дело в том, что ключ раздела является обязательным в запросе. Ключ сортировки используется только для получения диапазона данных

Срини Сидней
источник