Khóa chính Hash và Range là gì?


219

Tôi không thể hiểu khóa chính của Range ở đây là gì -

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

và làm như thế nào?

Ý nghĩa của "chỉ số băm không có thứ tự trên thuộc tính băm và chỉ số phạm vi được sắp xếp trên thuộc tính phạm vi" là gì?

Câu trả lời:


571

" Khóa chính băm và phạm vi " có nghĩa là một hàng duy nhất trong DynamoDB có một khóa chính duy nhất được tạo thành từ cả hàm băm và khóa phạm vi . Ví dụ: với khóa băm của X và khóa phạm vi của Y , khóa chính của bạn thực sự là XY . Bạn cũng có thể có nhiều khóa phạm vi cho cùng một khóa băm nhưng sự kết hợp phải là duy nhất, như XZXA . Hãy sử dụng các ví dụ của họ cho từng loại bảng:

Khóa chính băm - Khóa chính được tạo từ một thuộc tính, thuộc tính băm. Ví dụ: bảng ProductCatalog có thể có ProductID làm khóa chính. DynamoDB xây dựng một chỉ mục băm không có thứ tự trên thuộc tính khóa chính này.

Điều này có nghĩa là mọi hàng được khóa khỏi giá trị này. Mỗi hàng trong DynamoDB sẽ có một giá trị bắt buộc, duy nhất cho thuộc tính này . Chỉ số băm không có thứ tự có nghĩa là những gì được nói - dữ liệu không được sắp xếp và bạn không được đảm bảo về cách lưu trữ dữ liệu. Bạn sẽ không thể thực hiện truy vấn trên một chỉ số có thứ tự như Get tôi tất cả các hàng có một lớn hơn ProductID hơn X . Bạn viết và tìm nạp các mục dựa trên khóa băm. Ví dụ, Nhận cho tôi những dòng từ bảng mà có ProductID X . Bạn đang thực hiện một truy vấn đối với một chỉ mục không có thứ tự để việc bạn chống lại nó về cơ bản là tra cứu giá trị khóa, rất nhanh và sử dụng rất ít thông lượng.


Khóa chính Hash và Range - Khóa chính được tạo từ hai thuộc tính. Thuộc tính đầu tiên là thuộc tính băm và thuộc tính thứ hai là thuộc tính phạm vi. Ví dụ: bảng Chủ đề của diễn đàn có thể có ForumName và Chủ đề làm khóa chính của nó, trong đó ForumName là thuộc tính băm và Chủ đề là thuộc tính phạm vi. DynamoDB xây dựng một chỉ mục băm không có thứ tự trên thuộc tính băm và một chỉ mục phạm vi được sắp xếp trên thuộc tính phạm vi.

Điều này có nghĩa là khóa chính của mỗi hàng là sự kết hợp của khóa băm và phạm vi . Bạn có thể thực hiện trực tiếp trên các hàng đơn nếu bạn có cả khóa băm và phạm vi hoặc bạn có thể thực hiện truy vấn đối với chỉ mục phạm vi được sắp xếp . Ví dụ: hãy lấy cho tôi tất cả các hàng từ bảng có khóa Hash X có các khóa phạm vi lớn hơn Y hoặc các truy vấn khác ảnh hưởng đến nó. Chúng có hiệu suất tốt hơn và sử dụng ít dung lượng hơn so với Quét và Truy vấn đối với các trường không được lập chỉ mục. Từ tài liệu của họ :

Kết quả truy vấn luôn được sắp xếp theo khóa phạm vi. Nếu kiểu dữ liệu của khóa phạm vi là Số, kết quả được trả về theo thứ tự số; mặt khác, các kết quả được trả về theo thứ tự các giá trị mã ký tự ASCII. Theo mặc định, thứ tự sắp xếp tăng dần. Để đảo ngược thứ tự, đặt tham số ScanIndexForward thành false

Tôi có thể đã bỏ lỡ một số điều khi tôi gõ nó ra và tôi chỉ bị trầy xước bề mặt. Có rất nhiều khía cạnh khác cần xem xét khi làm việc với các bảng DynamoDB (thông lượng, tính nhất quán, năng lực, các chỉ số khác, phân phối khóa, v.v.). Bạn nên xem các bảng mẫu và trang dữ liệu để biết ví dụ.


53
đây là một trong những câu trả lời tràn ngăn xếp hữu ích nhất mà tôi từng đọc.
Tommy

7
Tại sao không có tùy chọn chỉ sử dụng phạm vi mà không có hàm băm? Ví dụ: nếu tất cả dữ liệu của tôi được lưu trữ với dấu thời gian của chúng làm khóa chính, tôi sẽ muốn có thể chọn "tất cả dữ liệu trong khoảng thời gian từ 2 đến 4 giờ chiều ngày 15/10/2015"
Teofrostus

3
@Teofrostus, khóa băm được sử dụng để xác định phân vùng chứa (các) mục. Nếu không có nó, DynamoDB sẽ không tìm phân vùng nào. Không biết tìm ở đâu để đánh bại Truy vấn và là trường hợp sử dụng cho Quét (hoặc Chỉ mục phụ toàn cầu, nhưng không phù hợp với trường hợp sử dụng của bạn không sử dụng gì ngoài thời gian loạt để chọn dữ liệu).
sheldonh

1
@mkobit có cách nào để tôi có thể truy xuất tất cả các khóa sắp xếp được cung cấp khóa phân vùng mà không cần quét không?
Unknownerror

1
@VNR Tôi không chắc là tôi hiểu câu hỏi của bạn trong ngữ cảnh của DynamoDB. Bạn có nói lấy tất cả các khóa băm + phạm vi khi cung cấp khóa băm không?
mkobit

19

Khi toàn bộ mọi thứ đang trộn lẫn, hãy nhìn vào chức năng và mã của nó để mô phỏng ý nghĩa của nó một cách rõ ràng

Cách duy nhất để có được một hàng là thông qua khóa chính

getRow(pk: PrimaryKey): Row

Cấu trúc dữ liệu chính có thể là:

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

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

Tuy nhiên, bạn có thể quyết định khóa chính của mình là khóa phân vùng + khóa sắp xếp trong trường hợp này:

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

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

Vì vậy, điểm mấu chốt:

  1. Quyết định rằng khóa chính của bạn chỉ là khóa phân vùng? lấy hàng đơn bằng phím phân vùng.

  2. Quyết định rằng khóa chính của bạn là khóa phân vùng + khóa sắp xếp? 2.1 Nhận một hàng theo (khóa phân vùng, khóa sắp xếp) hoặc nhận phạm vi của các hàng theo (khóa phân vùng)

Theo một cách nào đó, bạn nhận được một hàng bằng khóa chính, câu hỏi duy nhất là nếu bạn xác định khóa chính đó chỉ là khóa phân vùng hoặc khóa phân vùng + khóa sắp xếp

Các khối xây dựng là:

  1. Bàn
  2. Mục
  3. Thuộc tính KV.

Hãy nghĩ về Item là một hàng và thuộc tính KV như các ô trong hàng đó.

  1. Bạn có thể lấy một mục (một hàng) bằng khóa chính.
  2. Bạn có thể nhận được nhiều mục (nhiều hàng) bằng cách chỉ định (HashKey, RangeKeyQuery)

Bạn chỉ có thể làm (2) nếu bạn quyết định rằng PK của bạn bao gồm (HashKey, SortKey).

Trực quan hơn là phức tạp của nó, theo cách tôi nhìn thấy nó:

+----------------------------------------------------------------------------------+
|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                   ||
|                 +-----------+   +---------------+    |                          ||
|                                                      +--------------------------+|
+----------------------------------------------------------------------------------+

Vì vậy, những gì đang xảy ra ở trên. Lưu ý các quan sát sau đây. Như chúng tôi đã nói dữ liệu của chúng tôi thuộc về (Bảng, Mục, KVAttribution). Sau đó, mỗi mục có một khóa chính. Bây giờ cách bạn soạn khóa chính đó có ý nghĩa với cách bạn có thể truy cập dữ liệu.

Nếu bạn quyết định rằng PrimaryKey của bạn chỉ đơn giản là một khóa băm thì thật tuyệt, bạn có thể lấy một mục từ nó. Tuy nhiên, nếu bạn quyết định rằng khóa chính của bạn là hashKey + SortKey thì bạn cũng có thể thực hiện một truy vấn phạm vi trên khóa chính của mình bởi vì bạn sẽ nhận được các mục của mình bằng (HashKey + someRangeFunction (trên khóa phạm vi)). Vì vậy, bạn có thể nhận được nhiều mục với truy vấn khóa chính của bạn.

Lưu ý: Tôi không đề cập đến các chỉ mục phụ.


4

Một câu trả lời được giải thích rõ ràng đã được đưa ra bởi @mkobit, nhưng tôi sẽ thêm một bức tranh lớn về khóa phạm vi và khóa băm.

Nói một cách đơn giản, range + hash key = composite primary key CoreComponents của Dynamodb nhập mô tả hình ảnh ở đây

Khóa chính bao gồm khóa băm và khóa phạm vi tùy chọn. Khóa băm được sử dụng để chọn phân vùng DynamoDB. Phân vùng là một phần của dữ liệu bảng. Các phím phạm vi được sử dụng để sắp xếp các mục trong phân vùng, nếu chúng tồn tại.

Vì vậy, cả hai có một mục đích khác nhau và cùng nhau giúp thực hiện truy vấn phức tạp. Trong ví dụ trên hashkey1 can have multiple n-range.Một ví dụ khác về phạm vi và hashkey là trò chơi, userA (hashkey)có thể chơi Ngame(range)

nhập mô tả hình ảnh ở đây

Bảng Âm nhạc được mô tả trong Bảng, Mục và Thuộc tính là một ví dụ về bảng có khóa chính tổng hợp (Artist và SongTitle). Bạn có thể truy cập trực tiếp bất kỳ mục nào trong bảng Âm nhạc, nếu bạn cung cấp các giá trị Nghệ sĩ và Bài hát cho mục đó.

Khóa chính tổng hợp cung cấp cho bạn tính linh hoạt bổ sung khi truy vấn dữ liệu. Ví dụ: nếu bạn chỉ cung cấp giá trị cho Artist, DynamoDB sẽ lấy tất cả các bài hát của nghệ sĩ đó. Để chỉ truy xuất một tập hợp con các bài hát của một nghệ sĩ cụ thể, bạn có thể cung cấp một giá trị cho Nghệ sĩ cùng với một loạt các giá trị cho SongTitle.

nhập mô tả hình ảnh ở đây

https://www.sl slideshoware.net/InfoQ/amazon-dynamodb-design-potypes-best-practices https://www.sl slideshoware.net/AmazonWebService/awsome-day-2016-module-4-database-amazon-dynamodb -and-amazon-rds https://ceyhunozgun.blogspot.com/2017/04/im Hiệning-object -persistence-with-ynamodb.html


Trong ví dụ với Musicbảng, một nghệ sĩ không thể tạo ra hai bài hát có cùng tiêu đề, nhưng thật bất ngờ - trong các trò chơi video, chúng tôi có Doom từ năm 1993 và Doom từ năm 2016 en.wikipedia.org/wiki/Doom_(franchise) với cùng một "nghệ sĩ" ( nhà phát triển) : id Software.
Vitaly Zdanevich

0

@vnr bạn có thể truy xuất tất cả các khóa sắp xếp được liên kết với khóa phân vùng chỉ bằng cách sử dụng truy vấn bằng khóa chia tay. Không cần quét. Điểm ở đây là khóa phân vùng là bắt buộc trong một truy vấn. Khóa sắp xếp chỉ được sử dụng để nhận phạm vi dữ liệu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.