Що таке первинний ключ хешу та діапазону?


219

Я не в змозі зрозуміти, який тут основний ключ діапазону -

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

і як це працює?

Що вони означають під "не упорядкованим хеш-індексом на атрибуті хешу та відсортованим індексом діапазону на атрибуті діапазону"?

Відповіді:


571

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

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

Це означає, що кожен рядок відключається від цього значення. Кожен рядок в DynamoDB матиме необхідне унікальне значення для цього атрибута . Не упорядкований хеш-індекс означає те, що говориться - дані не впорядковані, і вам не дано жодних гарантій того, як зберігаються дані. Ви не зможете робити запити на невпорядкований індексу , такі як Отримати мені все рядки , які мають ProductID більше , ніж X . Ви пишете та вибираєте елементи на основі хеш-ключа. Наприклад, возьмімня рядок з цієї таблиці , яка має ProductID X . Ви робите запит проти невпорядкованого індексу, тому ваші показники, отримані проти нього, в основному шукають ключові значення, дуже швидкі та використовують дуже мало пропускної здатності.


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

Це означає, що первинний ключ кожного ряду - це комбінація хеша та ключа діапазону . Ви можете зробити прямі попадання в один рядок, якщо у вас є і хеш, і ключ діапазону, або ви можете зробити запит проти відсортованого індексу діапазону . Наприклад, дістаньте Отримати мені всі рядки з таблиці за допомогою клавіші Hash X, у яких клавіші діапазону перевищують Y , або інші запити, які впливають на це. Вони мають кращу продуктивність та менше використання потужностей порівняно зі скануваннями та запитами щодо полів, які не індексуються. З їх документації :

Результати запиту завжди сортуються за клавішею діапазону. Якщо тип даних ключа діапазону є Число, результати повертаються в числовому порядку; в іншому випадку результати повертаються в порядку значень коду символів ASCII. За замовчуванням порядок сортування зростає. Щоб змінити порядок, встановіть для параметра ScanIndexForward значення false

Напевно, я пропустив деякі речі, коли я це набрав, і я лише подряпав поверхню. Існує набагато більше аспектів, які слід враховувати при роботі з таблицями DynamoDB (пропускна здатність, узгодженість, ємність, інші показники, розподіл ключів тощо). Ви можете подивитися приклади таблиць та сторінки даних для прикладів.


53
це одна з найкорисніших відповідей на переповнення стека, яку я коли-небудь читав.
Томмі

7
Чому не існує можливості використовувати лише діапазон без хешу? Наприклад, якщо всі мої дані зберігаються з часовою позначкою в якості основного ключа, я б хотів мати можливість вибрати "всі дані між 14 та 16:00 15.10.2015"
Teofrostus

3
@Teofrostus, хеш-ключ використовується для ідентифікації розділу, який містить елементи. Без цього DynamoDB не мав би в якому розділі шукати. Не знаючи, куди шукати, перемагає Запит, і це випадок використання для сканування (або глобального вторинного індексу, але це не підходить для вашого випадку використання, якщо не використовувати нічого, крім часу серія для вибору даних).
sheldonh

1
@mkobit Чи є якийсь спосіб я отримати всі сортування ключів розділу ключа, не роблячи сканування?
невідомий

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.

Подумайте про предмет як рядок, а атрибут 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                   ||
|                 +-----------+   +---------------+    |                          ||
|                                                      +--------------------------+|
+----------------------------------------------------------------------------------+

Отже, що відбувається вище. Зауважте наступні зауваження. Як ми говорили, наші дані належать (Таблиця, Елемент, KVAttribute). Тоді кожен елемент має первинний ключ. Тепер те, як ви складаєте цей первинний ключ, має сенс у тому, як ви можете отримати доступ до даних.

Якщо ви вирішите, що ваш PrimaryKey - це просто хеш-ключ, то чудово, ви можете отримати з нього один предмет. Якщо ви вирішите, що основним вашим ключем є хеш-ключ + SortKey, ви також можете виконати запит про діапазон у своєму первинному ключі, оскільки ви отримаєте свої товари за допомогою (HashKey + SomeRangeFunction (на діапазоні)). Таким чином, ви можете отримати кілька предметів за допомогою вашого запиту первинного ключа.

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


4

Добре пояснену відповідь вже дає @mkobit, але я додам велику картину клавіші діапазону та хеш-ключа.

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

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

Тому обидва мають різну мету і разом допомагають робити складний запит. У наведеному вище прикладі hashkey1 can have multiple n-range.Ще одним прикладом діапазону та хешкею є гра, userA (hashkey)може грати в Ngame(range)

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

Музична таблиця, описана в таблицях, елементах та атрибутах, є прикладом таблиці з складеним первинним ключем (Artist і SongTitle). Ви можете отримати доступ до будь-якого елемента таблиці "Музика" безпосередньо, якщо вказати значення виконавця та SongTitle для цього елемента.

Складений первинний ключ надає додаткову гнучкість при запиті даних. Наприклад, якщо ви надаєте лише значення виконавця, DynamoDB отримує всі пісні цього виконавця. Щоб отримати лише підмножину пісень певного виконавця, ви можете надати значення виконавця разом із діапазоном значень для 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


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

0

@vnr ви можете отримати всі ключові слова, пов’язані з ключем розділу, просто використовуючи запит за допомогою розділу розбиття. Не потрібно сканування. Справа тут у тому, що ключ розділу є обов’язковим у запиті. Клавіша сортування використовується лише для отримання діапазону даних

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.