คีย์หลักของแฮชและช่วงคืออะไร


219

ฉันไม่สามารถเข้าใจว่าคีย์หลักของช่วงคืออะไรที่นี่ -

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

และมันทำงานอย่างไร

"แฮชดัชนีที่ไม่ได้เรียงลำดับบนแอตทริบิวต์แฮชและดัชนีช่วงที่จัดเรียงบนแอตทริบิวต์ช่วง" หมายความว่าอย่างไร

คำตอบ:


571

" คีย์หลักของแฮชและช่วง " หมายความว่าแถวเดียวใน DynamoDB มีคีย์หลักที่ไม่ซ้ำกันซึ่งประกอบด้วยทั้งแฮชและคีย์ช่วง ตัวอย่างเช่นมีคีย์กัญชาของXและที่สำคัญช่วงของY , คีย์หลักของคุณได้อย่างมีประสิทธิภาพXY นอกจากนี้คุณยังสามารถมีกุญแจช่วงหลายสำหรับคีย์กัญชาเหมือนกัน แต่รวมกันต้องไม่ซ้ำกันเช่นXZและXA ลองใช้ตัวอย่างสำหรับแต่ละประเภทของตาราง:

Hash Primary Key - คีย์หลักทำจากหนึ่งคุณลักษณะคือแอตทริบิวต์ hash ตัวอย่างเช่นตาราง ProductCatalog สามารถมี ProductID เป็นคีย์หลัก DynamoDB สร้างดัชนีแฮชที่ไม่มีการเรียงลำดับบนคีย์หลักนี้

ซึ่งหมายความว่าทุกแถวถูกคีย์จากค่านี้ ทุกแถวใน DynamoDB จะมีค่าที่ไม่ซ้ำกันและจำเป็นสำหรับแอตทริบิวต์นี้ ดัชนีแฮชที่ไม่ได้เรียงลำดับหมายถึงสิ่งที่ถูกพูด - ข้อมูลจะไม่ถูกเรียงลำดับและคุณจะไม่ได้รับการรับประกันว่าจะเก็บข้อมูลอย่างไร คุณจะไม่สามารถที่จะทำให้คำสั่งในดัชนีเรียงลำดับเช่นรับฉันทุกแถวที่มีมากขึ้นกว่า ProductID X คุณเขียนและดึงข้อมูลรายการตามคีย์แฮช ยกตัวอย่างเช่นรับฉันแถวจากตารางที่มี ProductID เอ็กซ์ คุณกำลังทำแบบสอบถามกับดัชนีที่ไม่มีการเรียงลำดับดังนั้นสิ่งที่คุณได้รับคือการค้นหาคีย์ - ค่ารวดเร็วและใช้ปริมาณงานน้อยมาก


คีย์หลักแฮชและช่วง - คีย์หลักทำจากสองแอตทริบิวต์ แอตทริบิวต์แรกคือแอตทริบิวต์ hash และแอตทริบิวต์ที่สองคือแอตทริบิวต์ช่วง ตัวอย่างเช่นตารางเธรดฟอรัมสามารถมี ForumName และ Subject เป็นคีย์หลักโดยที่ ForumName คือแอตทริบิวต์แฮชและหัวเรื่องเป็นแอตทริบิวต์ช่วง DynamoDB สร้างดัชนีแฮชที่ไม่ได้เรียงลำดับบนแอ็ตทริบิวต์แฮชและดัชนีช่วงที่เรียงลำดับบนแอ็ตทริบิวต์ช่วง

ซึ่งหมายความว่าคีย์หลักทุกแถวคือการรวมกันของกัญชาและช่วงที่สำคัญ คุณสามารถทำให้ตรงได้รับในแถวเดียวถ้าคุณมีทั้งกัญชาและช่วงที่สำคัญหรือคุณสามารถสร้างแบบสอบถามกับที่ดัชนีช่วงเรียง ตัวอย่างเช่นรับแถวทั้งหมดจากตารางด้วย Hash key X ที่มีปุ่มช่วงที่มากกว่า Yหรือแบบสอบถามอื่น ๆ ที่ส่งผลกระทบต่อ พวกเขามีประสิทธิภาพที่ดีขึ้นและการใช้ความจุน้อยกว่าเมื่อเปรียบเทียบกับ Scans และ Query กับเขตข้อมูลที่ไม่ได้จัดทำดัชนี จากเอกสารของพวกเขา :

ผลลัพธ์ของแบบสอบถามจะถูกจัดเรียงตามคีย์พิสัยเสมอ หากชนิดข้อมูลของช่วงคีย์เป็น Number ผลลัพธ์จะถูกส่งคืนตามลำดับตัวเลข มิฉะนั้นผลลัพธ์จะถูกส่งคืนตามลำดับของรหัสอักขระ ASCII ตามค่าเริ่มต้นเรียงลำดับขึ้น หากต้องการกลับคำสั่งซื้อให้ตั้งค่าพารามิเตอร์ ScanIndexForward เป็น false

ฉันอาจจะพลาดบางสิ่งบางอย่างเมื่อฉันพิมพ์สิ่งนี้ออกมา มีเป็นจำนวนมากมากขึ้นด้านที่จะต้องคำนึงถึงเมื่อทำงานกับตารางที่ DynamoDB (ผ่านสม่ำเสมอกำลังการผลิต, ดัชนีอื่น ๆ จัดจำหน่ายที่สำคัญอื่น ๆ ) คุณควรดูตัวอย่างตารางและหน้าข้อมูลสำหรับตัวอย่าง


53
นี่เป็นหนึ่งในคำตอบที่มีประโยชน์ที่สุดสำหรับกองซ้อนที่ฉันเคยอ่าน
Tommy

7
เหตุใดจึงไม่มีตัวเลือกให้ใช้เฉพาะช่วงที่ไม่มีแฮชเท่านั้น ตัวอย่างเช่นหากข้อมูลทั้งหมดของฉันถูกเก็บไว้ด้วยการประทับเวลาของพวกเขาเป็นคีย์หลักฉันต้องการที่จะสามารถเลือก "ข้อมูลทั้งหมดระหว่าง 2 ถึง 4 PM ในวันที่ 10/15/2015"
Teofrostus

3
@Teofrostus, คีย์แฮชใช้เพื่อระบุพาร์ติชันที่มีรายการ หากไม่มีมัน DynamoDB จะไม่ใช้พาร์ทิชันใด ๆ ในการมองหาไม่รู้จะหา Query ได้อย่างไรและเป็นกรณีการใช้งานสำหรับการสแกน (หรือ Global Secondary Index แต่ไม่เหมาะสำหรับกรณีการใช้งานของคุณโดยไม่มีเวลา ซีรีส์เพื่อเลือกข้อมูล)
sheldonh

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

คิดว่ารายการเป็นแถวและของ KV แอตทริบิวต์เป็นเซลล์ในแถวนั้น

  1. คุณสามารถรับไอเท็ม (แถว) โดยคีย์หลัก
  2. คุณสามารถรับหลายรายการ (หลายแถว) โดยการระบุ (HashKey, RangeKeyQuery)

คุณสามารถทำได้ (2) เฉพาะเมื่อคุณตัดสินใจว่า PK ของคุณประกอบด้วย (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 range และ hash key

ในคำง่ายๆrange + hash key = composite primary key CoreComponents ของ Dynamodb ป้อนคำอธิบายรูปภาพที่นี่

คีย์หลักประกอบด้วยคีย์แฮชและคีย์ช่วงเพิ่มเติม ใช้แฮชคีย์เพื่อเลือกพาร์ติชัน DynamoDB พาร์ติชันเป็นส่วนหนึ่งของข้อมูลตาราง ปุ่มพิสัยใช้เพื่อจัดเรียงรายการในพาร์ติชันหากมีอยู่

ดังนั้นทั้งสองมีวัตถุประสงค์ที่แตกต่างกันและช่วยกันทำแบบสอบถามที่ซับซ้อน ในตัวอย่างข้างต้นhashkey1 can have multiple n-range.อีกตัวอย่างหนึ่งของช่วงและแฮชคีย์คือเกม userA (hashkey)สามารถเล่น Ngame(range)

ป้อนคำอธิบายรูปภาพที่นี่

ตารางเพลงที่อธิบายไว้ในตารางรายการและคุณสมบัติเป็นตัวอย่างของตารางที่มีคีย์หลักผสม (ศิลปินและ SongTitle) คุณสามารถเข้าถึงรายการใด ๆ ในตาราง Music โดยตรงหากคุณระบุค่า Artist และ SongTitle สำหรับรายการนั้น

คีย์หลักแบบคอมโพสิตให้ความยืดหยุ่นเพิ่มเติมแก่คุณเมื่อสืบค้นข้อมูล ตัวอย่างเช่นหากคุณให้เฉพาะค่าสำหรับศิลปิน DynamoDB จะดึงเพลงทั้งหมดโดยศิลปินนั้น หากต้องการดึงเฉพาะเพลงบางเพลงโดยศิลปินเฉพาะคุณสามารถระบุค่าสำหรับศิลปินพร้อมกับช่วงของค่าสำหรับ SongTitle

ป้อนคำอธิบายรูปภาพที่นี่

https://www.slideshare.net/InfoQ/amazon-dynamodb-design-patterns-best-practices https://www.slideshare.net/AmazonWebServices/awsome-day-2016-module-4-database-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)ด้วย "artist" เดียวกัน ( id Softwareนักพัฒนา):
Vitaly Zdanevich

0

@vnr คุณสามารถดึงข้อมูลคีย์การเรียงลำดับทั้งหมดที่เกี่ยวข้องกับพาร์ติชันคีย์ได้โดยเพียงแค่ใช้แบบสอบถามโดยใช้คีย์พาร์ติชัน ไม่ต้องสแกน จุดที่นี่คือพาร์ทิชันคีย์เป็นข้อบังคับในแบบสอบถาม คีย์การเรียงลำดับใช้เพื่อรับช่วงข้อมูลเท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.