Chỉ mục là một phần quan trọng trong việc lập mô hình dữ liệu phù hợp cho tất cả cơ sở dữ liệu và DynamoDB cũng không ngoại lệ. Các chỉ mục phụ của DynamoDB là một công cụ mạnh mẽ để kích hoạt các mẫu truy cập mới cho dữ liệu của bạn.
Trong bài đăng này, chúng ta sẽ xem xét các chỉ mục phụ của DynamoDB . Trước tiên, chúng ta sẽ bắt đầu với một số điểm mang tính khái niệm về cách nghĩ về DynamoDB và các vấn đề mà chỉ mục phụ giải quyết. Sau đó, chúng ta sẽ xem xét một số mẹo thiết thực để sử dụng chỉ mục phụ một cách hiệu quả. Cuối cùng, chúng tôi sẽ kết thúc bằng một số suy nghĩ về khi nào bạn nên sử dụng các chỉ mục phụ và khi nào bạn nên tìm kiếm các giải pháp khác.
Bắt đầu nào.
Trước khi đi vào các trường hợp sử dụng và phương pháp hay nhất cho chỉ mục phụ, trước tiên chúng ta nên hiểu chỉ mục phụ DynamoDB là gì. Và để làm được điều đó, chúng ta nên hiểu một chút về cách hoạt động của DynamoDB.
Điều này giả định một số hiểu biết cơ bản về DynamoDB. Chúng tôi sẽ đề cập đến những điểm cơ bản bạn cần biết để hiểu về chỉ mục phụ, nhưng nếu mới làm quen với DynamoDB, bạn có thể muốn bắt đầu bằng phần giới thiệu cơ bản hơn.
DynamoDB là một cơ sở dữ liệu độc đáo. Nó được thiết kế cho khối lượng công việc OLTP, nghĩa là nó rất phù hợp để xử lý khối lượng lớn các hoạt động nhỏ -- hãy nghĩ đến những việc như thêm một mặt hàng vào giỏ hàng, thích một video hoặc thêm nhận xét trên Reddit. Bằng cách đó, nó có thể xử lý các ứng dụng tương tự như các cơ sở dữ liệu khác mà bạn có thể đã sử dụng, như MySQL, PostgreSQL, MongoDB hoặc Cassandra.
Lời hứa chính của DynamoDB là đảm bảo hiệu suất ổn định ở mọi quy mô . Cho dù bảng của bạn có 1 megabyte dữ liệu hay 1 petabyte dữ liệu, DynamoDB muốn có cùng độ trễ cho các yêu cầu giống OLTP của bạn. Đây là một vấn đề lớn -- nhiều cơ sở dữ liệu sẽ thấy hiệu suất giảm khi bạn tăng lượng dữ liệu hoặc số lượng yêu cầu đồng thời. Tuy nhiên, việc cung cấp những đảm bảo này đòi hỏi một số đánh đổi và DynamoDB có một số đặc điểm riêng mà bạn cần hiểu để sử dụng nó một cách hiệu quả.
Đầu tiên, DynamoDB mở rộng quy mô cơ sở dữ liệu của bạn theo chiều ngang bằng cách trải rộng dữ liệu của bạn trên nhiều phân vùng. Những phân vùng này không hiển thị với bạn với tư cách là người dùng nhưng chúng là cốt lõi trong cách hoạt động của DynamoDB. Bạn sẽ chỉ định khóa chính cho bảng của mình (một thành phần duy nhất, được gọi là 'khóa phân vùng' hoặc kết hợp khóa phân vùng và khóa sắp xếp) và DynamoDB sẽ sử dụng khóa chính đó để xác định dữ liệu của bạn nằm trên phân vùng nào . Mọi yêu cầu bạn thực hiện sẽ đi qua bộ định tuyến yêu cầu để xác định phân vùng nào sẽ xử lý yêu cầu đó. Các phân vùng này có kích thước nhỏ -- thường là 10 GB trở xuống -- vì vậy chúng có thể được di chuyển, phân tách, sao chép và quản lý độc lập.
Khả năng mở rộng theo chiều ngang thông qua phân đoạn là điều thú vị nhưng không có nghĩa là chỉ có ở DynamoDB. Nhiều cơ sở dữ liệu khác -- cả quan hệ và không quan hệ -- sử dụng phân đoạn để mở rộng quy mô theo chiều ngang. Tuy nhiên, điểm độc đáo của DynamoDB là cách nó buộc bạn phải sử dụng khóa chính để truy cập dữ liệu của mình. Thay vì sử dụng trình lập kế hoạch truy vấn để chuyển yêu cầu của bạn thành một chuỗi truy vấn, DynamoDB buộc bạn phải sử dụng khóa chính để truy cập dữ liệu của mình. Về cơ bản, bạn đang nhận được một chỉ mục có thể định địa chỉ trực tiếp cho dữ liệu của mình.
API cho DynamoDB phản ánh điều này. Có một loạt thao tác trên từng mục riêng lẻ ( GetItem
, PutItem
, UpdateItem
, DeleteItem
) cho phép bạn đọc, viết và xóa từng mục riêng lẻ. Ngoài ra, còn có thao tác Query
cho phép bạn truy xuất nhiều mục có cùng khóa phân vùng. Nếu bạn có một bảng có khóa chính tổng hợp, các mục có cùng khóa phân vùng sẽ được nhóm lại với nhau trên cùng một phân vùng. Chúng sẽ được sắp xếp theo khóa sắp xếp, cho phép bạn xử lý các mẫu như "Tìm nạp các đơn đặt hàng gần đây nhất cho người dùng" hoặc "Tìm nạp 10 lần đọc cảm biến cuối cùng cho thiết bị IoT".
Ví dụ: hãy tưởng tượng một ứng dụng SaaS có bảng Người dùng. Tất cả Người dùng thuộc về một Tổ chức duy nhất. Chúng ta có thể có một bảng trông như sau:
Chúng tôi đang sử dụng khóa chính tổng hợp có khóa phân vùng là 'Tổ chức' và khóa sắp xếp là 'Tên người dùng'. Điều này cho phép chúng tôi thực hiện các thao tác tìm nạp hoặc cập nhật một Người dùng riêng lẻ bằng cách cung cấp Tổ chức và Tên người dùng của họ. Chúng tôi cũng có thể tìm nạp tất cả Người dùng cho một Tổ chức bằng cách chỉ cung cấp Tổ chức cho hoạt động Query
.
Với một số điều cơ bản, bây giờ chúng ta hãy xem xét các chỉ mục phụ. Cách tốt nhất để hiểu sự cần thiết của chỉ mục phụ là hiểu vấn đề mà chúng giải quyết. Chúng ta đã thấy cách DynamoDB phân vùng dữ liệu theo khóa chính của bạn và cách nó thúc đẩy bạn sử dụng khóa chính để truy cập dữ liệu của mình. Điều đó hoàn toàn ổn đối với một số kiểu truy cập, nhưng nếu bạn cần truy cập dữ liệu của mình theo cách khác thì sao?
Trong ví dụ ở trên, chúng tôi có một bảng người dùng mà chúng tôi truy cập theo tổ chức và tên người dùng của họ. Tuy nhiên, chúng tôi cũng có thể cần tìm nạp một người dùng theo địa chỉ email của họ. Mẫu này không phù hợp với mẫu truy cập khóa chính mà DynamoDB hướng tới. Bởi vì bảng của chúng tôi được phân vùng theo các thuộc tính khác nhau nên không có cách rõ ràng nào để truy cập dữ liệu theo cách chúng tôi muốn. Chúng tôi có thể quét toàn bộ bảng, nhưng việc đó chậm và không hiệu quả. Chúng tôi có thể sao chép dữ liệu của mình vào một bảng riêng biệt với khóa chính khác, nhưng điều đó sẽ làm tăng thêm độ phức tạp.
Đây là nơi xuất hiện các chỉ mục phụ. Về cơ bản, chỉ mục phụ là bản sao dữ liệu được quản lý hoàn toàn với một khóa chính khác. Bạn sẽ chỉ định chỉ mục phụ trên bảng của mình bằng cách khai báo khóa chính cho chỉ mục. Khi dữ liệu được ghi vào bảng của bạn, DynamoDB sẽ tự động sao chép dữ liệu vào chỉ mục phụ của bạn.
Lưu ý *: Mọi thứ trong phần này áp dụng cho chỉ mục phụ toàn cục . DynamoDB cũng cung cấp các chỉ mục phụ cục bộ , có một chút khác biệt. Trong hầu hết các trường hợp, bạn sẽ muốn có một chỉ mục phụ toàn cục. Để biết thêm chi tiết về sự khác biệt, hãy xem bài viết này về cách chọn chỉ mục phụ toàn cục hoặc cục bộ .*
Trong trường hợp này, chúng tôi sẽ thêm chỉ mục phụ vào bảng của mình bằng khóa phân vùng là "Email". Chỉ số phụ sẽ trông như sau:
Lưu ý rằng đây là cùng một dữ liệu, nó vừa được sắp xếp lại bằng khóa chính khác. Bây giờ, chúng ta có thể tra cứu người dùng theo địa chỉ email của họ một cách hiệu quả.
Ở một khía cạnh nào đó, điều này rất giống với chỉ mục trong các cơ sở dữ liệu khác. Cả hai đều cung cấp cấu trúc dữ liệu được tối ưu hóa để tra cứu trên một thuộc tính cụ thể. Tuy nhiên, các chỉ mục phụ của DynamoDB khác nhau ở một số điểm chính.
Đầu tiên và quan trọng nhất, các chỉ mục của DynamoDB nằm trên các phân vùng hoàn toàn khác với bảng chính của bạn. DynamoDB muốn mọi hoạt động tra cứu đều hiệu quả và có thể dự đoán được, đồng thời muốn cung cấp khả năng chia tỷ lệ tuyến tính theo chiều ngang. Để thực hiện việc này, nó cần phân chia lại dữ liệu của bạn theo các thuộc tính bạn sẽ sử dụng để truy vấn dữ liệu đó.
Trong các cơ sở dữ liệu phân tán khác, chúng thường không phân chia lại dữ liệu của bạn cho chỉ mục phụ. Họ thường sẽ chỉ duy trì chỉ mục phụ cho tất cả dữ liệu trên phân đoạn. Tuy nhiên, nếu các chỉ mục của bạn không sử dụng khóa phân đoạn thì bạn sẽ mất một số lợi ích của việc chia tỷ lệ dữ liệu theo chiều ngang vì một truy vấn không có khóa phân đoạn sẽ cần thực hiện thao tác thu thập phân tán trên tất cả các phân đoạn để tìm dữ liệu bạn 'Đang tìm kiếm.
Điểm khác biệt thứ hai của các chỉ mục phụ của DynamoDB là chúng (thường) sao chép toàn bộ mục vào chỉ mục phụ. Đối với các chỉ mục trên cơ sở dữ liệu quan hệ, chỉ mục thường sẽ chứa một con trỏ tới khóa chính của mục được lập chỉ mục. Sau khi định vị bản ghi có liên quan trong chỉ mục, cơ sở dữ liệu sẽ cần tìm nạp toàn bộ mục. Vì các chỉ mục phụ của DynamoDB nằm trên các nút khác với bảng chính nên chúng muốn tránh việc nhảy mạng trở lại mục ban đầu. Thay vào đó, bạn sẽ sao chép bao nhiêu dữ liệu bạn cần vào chỉ mục phụ để xử lý việc đọc của bạn.
Các chỉ mục phụ trong DynamoDB rất mạnh nhưng có một số hạn chế. Trước hết, chúng ở chế độ chỉ đọc - bạn không thể ghi trực tiếp vào chỉ mục phụ. Thay vào đó, bạn sẽ ghi vào bảng chính và DynamoDB sẽ xử lý việc sao chép sang chỉ mục phụ của bạn. Thứ hai, bạn bị tính phí cho các thao tác ghi vào chỉ mục phụ của mình. Do đó, việc thêm chỉ mục phụ vào bảng của bạn thường sẽ tăng gấp đôi tổng chi phí ghi cho bảng của bạn.
Bây giờ chúng ta đã hiểu chỉ mục phụ là gì và chúng hoạt động như thế nào, hãy nói về cách sử dụng chúng một cách hiệu quả. Chỉ mục phụ là một công cụ mạnh mẽ nhưng chúng có thể bị lạm dụng. Dưới đây là một số mẹo để sử dụng chỉ mục phụ một cách hiệu quả.
Mẹo đầu tiên có vẻ hiển nhiên -- chỉ mục phụ chỉ có thể được sử dụng để đọc, vì vậy bạn nên đặt mục tiêu có các mẫu chỉ đọc trên chỉ mục phụ của mình! Tuy nhiên, tôi luôn thấy lỗi này. Trước tiên, các nhà phát triển sẽ đọc từ chỉ mục phụ, sau đó ghi vào bảng chính. Điều này dẫn đến chi phí tăng thêm và độ trễ tăng thêm, đồng thời bạn thường có thể tránh được điều này bằng cách lập kế hoạch trước.
Nếu bạn đã đọc bất kỳ điều gì về lập mô hình dữ liệu DynamoDB thì có thể bạn biết rằng trước tiên bạn nên nghĩ đến các mẫu truy cập của mình. Nó không giống như một cơ sở dữ liệu quan hệ nơi trước tiên bạn thiết kế các bảng chuẩn hóa và sau đó viết các truy vấn để nối chúng lại với nhau. Trong DynamoDB, bạn nên suy nghĩ về các hành động mà ứng dụng của bạn sẽ thực hiện, sau đó thiết kế các bảng và chỉ mục để hỗ trợ các hành động đó.
Khi thiết kế bảng của mình, trước tiên tôi muốn bắt đầu với các mẫu truy cập dựa trên ghi. Với bài viết của mình, tôi thường duy trì một số loại ràng buộc -- tính duy nhất của tên người dùng hoặc số lượng thành viên tối đa trong một nhóm. Tôi muốn thiết kế bảng của mình theo cách làm cho việc này trở nên đơn giản, lý tưởng là không cần sử dụng Giao dịch DynamoDB hoặc sử dụng mẫu đọc-sửa đổi-ghi có thể phải tuân theo các điều kiện tương tranh.
Khi bạn thực hiện những điều này, nhìn chung bạn sẽ thấy rằng có một cách 'chính' để xác định mục phù hợp với kiểu viết của bạn. Đây sẽ là khóa chính của bạn. Sau đó, việc thêm vào các mẫu đọc phụ bổ sung thật dễ dàng với các chỉ mục phụ.
Trong ví dụ về Người dùng của chúng tôi trước đây, mọi yêu cầu của Người dùng có thể sẽ bao gồm Tổ chức và Tên người dùng. Điều này sẽ cho phép tôi tra cứu hồ sơ Người dùng riêng lẻ cũng như ủy quyền cho các hành động cụ thể của Người dùng. Việc tra cứu địa chỉ email có thể dành cho các kiểu truy cập ít nổi bật hơn, chẳng hạn như luồng 'quên mật khẩu' hoặc luồng 'tìm kiếm người dùng'. Đây là các mẫu chỉ đọc và chúng rất phù hợp với chỉ mục phụ.
Mẹo thứ hai để sử dụng chỉ mục phụ là sử dụng chúng cho các giá trị có thể thay đổi trong mẫu hình truy cập của bạn. Trước tiên chúng ta hãy hiểu lý do đằng sau nó và sau đó xem xét các tình huống áp dụng nó.
DynamoDB cho phép bạn cập nhật một mục hiện có bằng thao tác UpdateItem
. Tuy nhiên, bạn không thể thay đổi khóa chính của một mục trong bản cập nhật . Khóa chính là mã định danh duy nhất cho một mục và việc thay đổi khóa chính về cơ bản là tạo ra một mục mới. Nếu bạn muốn thay đổi khóa chính của một mục hiện có, bạn cần xóa mục cũ và tạo một mục mới. Quá trình hai bước này chậm hơn và tốn kém. Thông thường, trước tiên bạn cần đọc mục gốc, sau đó sử dụng giao dịch để xóa mục gốc và tạo mục mới trong cùng một yêu cầu.
Mặt khác, nếu bạn có giá trị có thể thay đổi này trong khóa chính của chỉ mục phụ thì DynamoDB sẽ xử lý quy trình xóa + tạo này cho bạn trong quá trình sao chép. Bạn có thể đưa ra một yêu cầu UpdateItem
đơn giản để thay đổi giá trị và DynamoDB sẽ xử lý phần còn lại.
Tôi thấy mô hình này xuất hiện trong hai tình huống chính. Đầu tiên và phổ biến nhất là khi bạn có một thuộc tính có thể thay đổi mà bạn muốn sắp xếp. Các ví dụ điển hình ở đây là bảng xếp hạng cho một trò chơi trong đó mọi người liên tục giành được điểm hoặc cho danh sách các mục được cập nhật liên tục mà bạn muốn hiển thị các mục được cập nhật gần đây nhất trước tiên. Hãy nghĩ đến một cái gì đó như Google Drive, nơi bạn có thể sắp xếp các tệp của mình theo 'sửa đổi lần cuối'.
Mẫu thứ hai xuất hiện là khi bạn có thuộc tính có thể thay đổi mà bạn muốn lọc. Ở đây, bạn có thể nghĩ đến một cửa hàng thương mại điện tử có lịch sử đặt hàng của người dùng. Bạn có thể muốn cho phép người dùng lọc đơn hàng của họ theo trạng thái -- hiển thị cho tôi tất cả các đơn hàng 'đã vận chuyển' hoặc 'đã giao'. Bạn có thể tích hợp mã này vào khóa phân vùng hoặc phần đầu của khóa sắp xếp để cho phép lọc đối sánh chính xác. Khi mục thay đổi trạng thái, bạn có thể cập nhật thuộc tính trạng thái và dựa vào DynamoDB để nhóm các mục một cách chính xác trong chỉ mục phụ của mình.
Trong cả hai trường hợp này, việc di chuyển thuộc tính có thể thay đổi này sang chỉ mục phụ sẽ giúp bạn tiết kiệm thời gian và tiền bạc. Bạn sẽ tiết kiệm thời gian bằng cách tránh kiểu đọc-sửa-ghi và bạn sẽ tiết kiệm tiền bằng cách tránh các chi phí ghi thêm của giao dịch.
Ngoài ra, hãy lưu ý rằng mẫu này rất phù hợp với mẹo trước. Bạn khó có thể xác định được mục để viết dựa trên thuộc tính có thể thay đổi như điểm trước đó, trạng thái trước đó hoặc lần cuối cùng chúng được cập nhật. Thay vào đó, bạn sẽ cập nhật bằng giá trị ổn định hơn, như ID người dùng, ID đơn đặt hàng hoặc ID của tệp. Sau đó, bạn sẽ sử dụng chỉ mục phụ để sắp xếp và lọc dựa trên thuộc tính có thể thay đổi.
Chúng ta đã thấy ở trên rằng DynamoDB chia dữ liệu của bạn thành các phân vùng dựa trên khóa chính. Mục đích của DynamoDB là giữ cho các phân vùng này ở mức nhỏ -- 10 GB trở xuống -- và bạn nên hướng đến việc phân bổ các yêu cầu trên các phân vùng của mình để tận dụng khả năng mở rộng của DynamoDB.
Điều này thường có nghĩa là bạn nên sử dụng giá trị lượng số cao trong khóa phân vùng của mình. Hãy nghĩ về những thứ như tên người dùng, ID đơn hàng hoặc ID cảm biến. Có rất nhiều giá trị cho các thuộc tính này và DynamoDB có thể phân bổ lưu lượng truy cập trên các phân vùng của bạn.
Thông thường, tôi thấy mọi người hiểu nguyên tắc này trong bảng chính của họ, nhưng sau đó lại hoàn toàn quên nó trong các chỉ mục phụ của họ. Thông thường, họ muốn đặt hàng trên toàn bộ bảng cho một loại mặt hàng. Nếu họ muốn truy xuất người dùng theo thứ tự bảng chữ cái, họ sẽ sử dụng chỉ mục phụ trong đó tất cả người dùng có USERS
làm khóa phân vùng và tên người dùng làm khóa sắp xếp. Hoặc, nếu họ muốn đặt hàng các đơn hàng gần đây nhất trong cửa hàng thương mại điện tử, họ sẽ sử dụng chỉ mục phụ trong đó tất cả các đơn hàng có ORDERS
làm khóa phân vùng và dấu thời gian làm khóa sắp xếp.
Mẫu này có thể hoạt động đối với các ứng dụng có lưu lượng truy cập nhỏ, nơi bạn không đạt đến giới hạn thông lượng phân vùng DynamoDB , nhưng đó là mẫu nguy hiểm đối với ứng dụng có lưu lượng truy cập cao. Tất cả lưu lượng truy cập của bạn có thể được chuyển đến một phân vùng vật lý duy nhất và bạn có thể nhanh chóng đạt giới hạn thông lượng ghi cho phân vùng đó.
Hơn nữa, và nguy hiểm nhất, điều này có thể gây ra sự cố cho bảng chính của bạn. Nếu chỉ mục phụ của bạn bị hạn chế ghi trong quá trình sao chép, hàng đợi sao chép sẽ được sao lưu. Nếu hàng đợi này sao lưu quá nhiều, DynamoDB sẽ bắt đầu từ chối hoạt động ghi trên bảng chính của bạn.
Điều này được thiết kế để giúp bạn -- DynamoDB muốn hạn chế tình trạng cũ kỹ của chỉ mục phụ của bạn, do đó, nó sẽ ngăn bạn sử dụng chỉ mục phụ có độ trễ lớn. Tuy nhiên, có thể có một tình huống đáng ngạc nhiên xảy ra vào lúc bạn ít mong đợi nhất.
Mọi người thường nghĩ đến các chỉ mục phụ như một cách để sao chép tất cả dữ liệu của họ bằng khóa chính mới. Tuy nhiên, bạn không cần tất cả dữ liệu của mình phải xuất hiện ở chỉ mục phụ. Nếu bạn có một mục không khớp với lược đồ khóa của chỉ mục, mục đó sẽ không được sao chép vào chỉ mục.
Điều này có thể thực sự hữu ích khi cung cấp bộ lọc chung cho dữ liệu của bạn. Ví dụ điển hình tôi sử dụng cho việc này là hộp thư đến. Trong bảng chính, bạn có thể lưu trữ tất cả tin nhắn cho một người dùng cụ thể được sắp xếp theo thời điểm chúng được tạo.
Nhưng nếu bạn giống tôi, bạn có rất nhiều thư trong hộp thư đến của mình. Hơn nữa, bạn có thể coi các tin nhắn chưa đọc như một danh sách 'việc cần làm', giống như những lời nhắc nhỏ để liên hệ lại với ai đó. Theo đó, tôi thường chỉ muốn xem những tin nhắn chưa đọc trong hộp thư đến của mình.
Bạn có thể sử dụng chỉ mục phụ của mình để cung cấp bộ lọc toàn cầu này ở những nơi unread == true
. Có lẽ khóa phân vùng chỉ mục phụ của bạn giống như ${userId}#UNREAD
và khóa sắp xếp là dấu thời gian của tin nhắn. Khi bạn tạo thư ban đầu, nó sẽ bao gồm giá trị khóa phân vùng chỉ mục phụ và do đó sẽ được sao chép sang chỉ mục phụ của thư chưa đọc. Sau này, khi người dùng đọc tin nhắn, bạn có thể thay đổi status
thành READ
và xóa giá trị khóa phân vùng chỉ mục phụ. DynamoDB sau đó sẽ xóa nó khỏi chỉ mục phụ của bạn.
Tôi thường xuyên sử dụng thủ thuật này và nó có hiệu quả rõ rệt. Hơn nữa, một chỉ mục thưa thớt sẽ giúp bạn tiết kiệm tiền. Mọi cập nhật để đọc thư sẽ không được sao chép sang chỉ mục phụ và bạn sẽ tiết kiệm được chi phí ghi.
Đối với mẹo cuối cùng của chúng tôi, hãy đưa điểm trước đó đi xa hơn một chút. Chúng tôi vừa thấy rằng DynamoDB sẽ không đưa một mục vào chỉ mục phụ của bạn nếu mục đó không có các thành phần khóa chính cho chỉ mục. Thủ thuật này có thể được sử dụng không chỉ cho các phần tử khóa chính mà còn cho các thuộc tính không khóa trong dữ liệu!
Khi tạo chỉ mục phụ, bạn có thể chỉ định thuộc tính nào từ bảng chính mà bạn muốn đưa vào chỉ mục phụ. Đây được gọi là phép chiếu của chỉ số. Bạn có thể chọn bao gồm tất cả các thuộc tính từ bảng chính, chỉ các thuộc tính khóa chính hoặc một tập hợp con của các thuộc tính.
Mặc dù việc đưa tất cả các thuộc tính vào chỉ mục phụ của bạn là điều hấp dẫn nhưng đây có thể là một sai lầm tốn kém. Hãy nhớ rằng mỗi lần ghi vào bảng chính làm thay đổi giá trị của thuộc tính dự kiến sẽ được sao chép sang chỉ mục phụ của bạn. Một chỉ mục phụ duy nhất với phép chiếu đầy đủ sẽ tăng gấp đôi chi phí ghi cho bảng của bạn một cách hiệu quả. Mỗi chỉ mục phụ bổ sung sẽ làm tăng chi phí ghi của bạn thêm 1/N + 1
, trong đó N
là số lượng chỉ mục phụ trước chỉ mục mới.
Ngoài ra, chi phí viết của bạn được tính dựa trên kích thước mặt hàng của bạn. Mỗi 1KB dữ liệu được ghi vào bảng của bạn sử dụng WCU. Nếu bạn đang sao chép một mục 4KB vào chỉ mục phụ, bạn sẽ phải trả toàn bộ 4 WCU trên cả bảng chính và chỉ mục phụ của mình.
Vì vậy, có hai cách để bạn có thể tiết kiệm tiền bằng cách thu hẹp các dự báo chỉ số phụ của mình. Đầu tiên, bạn có thể tránh hoàn toàn một số thao tác viết nhất định. Nếu bạn có thao tác cập nhật không chạm đến bất kỳ thuộc tính nào trong phép chiếu chỉ mục phụ, DynamoDB sẽ bỏ qua việc ghi vào chỉ mục phụ của bạn. Thứ hai, đối với những thao tác ghi sao chép sang chỉ mục phụ, bạn có thể tiết kiệm tiền bằng cách giảm kích thước của mục được sao chép.
Đây có thể là một sự cân bằng khó khăn để có được sự cân bằng đúng đắn. Các phép chiếu chỉ số phụ không thể thay đổi sau khi chỉ mục được tạo. Nếu bạn thấy rằng mình cần các thuộc tính bổ sung trong chỉ mục phụ của mình, bạn sẽ cần tạo một chỉ mục mới với phép chiếu mới rồi xóa chỉ mục cũ.
Bây giờ chúng ta đã khám phá một số lời khuyên thiết thực xung quanh các chỉ mục phụ, hãy lùi lại một bước và đặt một câu hỏi cơ bản hơn -- bạn có nên sử dụng chỉ mục phụ không?
Như chúng ta đã thấy, chỉ mục phụ giúp bạn truy cập dữ liệu của mình theo một cách khác. Tuy nhiên, điều này phải trả giá bằng việc viết thêm. Vì vậy, nguyên tắc nhỏ của tôi đối với các chỉ mục phụ là:
Sử dụng các chỉ mục phụ khi chi phí đọc giảm lớn hơn chi phí ghi tăng lên.
Điều này có vẻ hiển nhiên khi bạn nói ra nhưng nó có thể phản trực giác khi bạn làm mẫu. Có vẻ thật dễ dàng khi nói "Ném nó vào chỉ mục phụ" mà không cần suy nghĩ về các cách tiếp cận khác.
Để hiểu rõ điều này, chúng ta hãy xem xét hai tình huống trong đó các chỉ mục phụ có thể không có ý nghĩa.
Với DynamoDB, bạn thường muốn các khóa chính thực hiện quá trình lọc cho bạn. Tôi hơi khó chịu mỗi khi sử dụng Truy vấn trong DynamoDB nhưng sau đó thực hiện quá trình lọc của riêng mình trong ứng dụng của mình -- tại sao tôi không thể tích hợp truy vấn đó vào khóa chính?
Bất chấp phản ứng nội tạng của tôi, có một số trường hợp bạn có thể muốn đọc kỹ dữ liệu của mình và sau đó lọc trong ứng dụng của mình.
Nơi phổ biến nhất mà bạn sẽ thấy điều này là khi bạn muốn cung cấp nhiều bộ lọc khác nhau về dữ liệu của mình cho người dùng nhưng tập dữ liệu liên quan bị giới hạn.
Hãy nghĩ về một máy theo dõi tập luyện. Bạn có thể muốn cho phép người dùng lọc nhiều thuộc tính, chẳng hạn như loại hình tập luyện, cường độ, thời lượng, ngày tháng, v.v. Tuy nhiên, số lượng bài tập mà người dùng thực hiện sẽ có thể quản lý được -- ngay cả người dùng thành thạo cũng sẽ mất một thời gian để vượt quá 1000 bài tập. Thay vì đặt chỉ mục cho tất cả các thuộc tính này, bạn có thể tìm nạp tất cả các bài tập luyện của người dùng rồi lọc trong ứng dụng của mình.
Đây là nơi tôi khuyên bạn nên làm toán . DynamoDB giúp bạn dễ dàng tính toán hai tùy chọn này và biết được tùy chọn nào sẽ hoạt động tốt hơn cho ứng dụng của bạn.
Hãy thay đổi tình huống của chúng ta một chút -- nếu bộ sưu tập vật phẩm của chúng ta lớn thì sao? Điều gì sẽ xảy ra nếu chúng tôi đang xây dựng một công cụ theo dõi quá trình tập luyện cho một phòng tập thể dục và muốn cho phép chủ sở hữu phòng tập thể dục lọc tất cả các thuộc tính mà chúng tôi đã đề cập ở trên cho tất cả người dùng trong phòng tập thể dục ?
Điều này thay đổi tình hình. Bây giờ chúng ta đang nói về hàng trăm hoặc thậm chí hàng nghìn người dùng, mỗi người có hàng trăm hoặc hàng nghìn bài tập. Sẽ không có ý nghĩa gì nếu đọc kỹ toàn bộ bộ sưu tập vật phẩm và thực hiện lọc hậu kỳ trên kết quả.
Nhưng các chỉ mục phụ cũng không thực sự có ý nghĩa ở đây. Chỉ mục phụ phù hợp với các mẫu truy cập đã biết nơi bạn có thể tin tưởng vào các bộ lọc có liên quan hiện có. Nếu chúng tôi muốn chủ phòng tập thể dục của mình có thể lọc nhiều thuộc tính khác nhau, tất cả đều là tùy chọn, chúng tôi cần tạo một số lượng lớn chỉ mục để thực hiện việc này.
Trước đây chúng ta đã nói về những nhược điểm có thể có của trình lập kế hoạch truy vấn, nhưng trình lập kế hoạch truy vấn cũng có những mặt tích cực. Ngoài việc cho phép truy vấn linh hoạt hơn, họ cũng có thể thực hiện những việc như giao chỉ mục để xem kết quả một phần từ nhiều chỉ mục khi soạn các truy vấn này. Bạn có thể làm điều tương tự với DynamoDB, nhưng điều này sẽ dẫn đến ứng dụng của bạn phải thực hiện nhiều thao tác qua lại, cùng với một số logic ứng dụng phức tạp để tìm hiểu.
Khi gặp những loại vấn đề này, tôi thường tìm kiếm một công cụ phù hợp hơn cho trường hợp sử dụng này. Rockset và Elaticsearch là những đề xuất tôi nên áp dụng ở đây để cung cấp tính năng lọc linh hoạt, giống như chỉ mục phụ trên tập dữ liệu của bạn.
Trong bài đăng này, chúng ta đã tìm hiểu về các chỉ mục phụ của DynamoDB. Đầu tiên, chúng ta xem xét một số khái niệm để hiểu cách hoạt động của DynamoDB và lý do tại sao cần có chỉ mục phụ. Sau đó, chúng tôi đã xem xét một số mẹo thực tế để hiểu cách sử dụng các chỉ mục phụ một cách hiệu quả và tìm hiểu những đặc điểm riêng biệt của chúng. Cuối cùng, chúng ta đã xem xét cách nghĩ về các chỉ mục phụ để biết khi nào bạn nên sử dụng các phương pháp khác.
Các chỉ mục phụ là một công cụ mạnh mẽ trong hộp công cụ DynamoDB của bạn, nhưng chúng không phải là viên đạn bạc. Giống như tất cả mô hình hóa dữ liệu DynamoDB, hãy đảm bảo bạn xem xét cẩn thận các kiểu truy cập của mình và tính toán chi phí trước khi bắt tay vào thực hiện.
Tìm hiểu thêm về cách bạn có thể sử dụng Rockset để lọc giống như chỉ mục phụ trong blog của Alex DeBrie Truy vấn tổng hợp và lọc DynamoDB bằng cách sử dụng SQL trên Rockset .