Làm thế nào tôi nên thiết kế một tài nguyên danh sách theo thứ tự trong một dịch vụ yên tĩnh?


11

Tôi đã gặp vấn đề tương tự hết lần này đến lần khác và tôi không tìm thấy giải pháp nào mà tôi thực sự cảm thấy là tối ưu.

Nói trong một ứng dụng, bạn có một danh sách được sắp xếp và bạn cho phép người dùng thay đổi thứ tự đó bằng cách kéo và thả hoặc một cái gì đó. Bạn muốn những thay đổi theo thứ tự để tiếp tục. Làm thế nào để bạn mô hình đó?

Làm thế nào tôi nên thiết kế một dịch vụ đầy đủ của một tài nguyên danh sách theo thứ tự?

Cụ thể, tôi nên thiết kế listitemmô hình tài nguyên yên tĩnh như thế nào? Việc thiết kế phổ biến nhất tôi đã nhìn thấy là itemthực thể có một orderhoặc positiontài sản. Một cách tiếp cận khác mà tôi đã nghe là một danh sách liên kết đôi trên các mặt hàng.

Cách tiếp cận nào không ghi quá nhiều vào cơ sở dữ liệu và thường nhanh chóng cập nhật và đọc cho khách hàng? Làm thế nào các điểm cuối nên được tiếp xúc như?


Vì tò mò, tại sao điều quan trọng là phải trả lại một danh sách được đặt hàng cụ thể?
Adam Wells

Chà tôi đoán tôi không đặc biệt mong muốn trả lại tài nguyên danh sách theo thứ tự mà chỉ duy trì thứ tự / vị trí của tài nguyên có thể là một phần của tài nguyên danh sách thực tế hoặc chỉ là một phần của danh sách. Tôi muốn nói rằng hãy để người dùng thay đổi thứ tự công việc trong danh sách các todos. Nhưng không có vấn đề gì vẫn còn một danh sách mà thứ tự quan trọng. Những gì tôi không thể tìm thấy là một cách tốt để thiết kế này
Rico Kahler

Câu trả lời:


14

Đại diện cho một danh sách theo thứ tự là một trong những vấn đề khó khăn với cơ sở dữ liệu quan hệ. Thêm một thuộc tính vị trí vào mối quan hệ thành viên danh sách là cách phổ biến nhất để làm điều này, vì bạn có thể dễ dàng truy xuất danh sách được sắp xếp bằng cách thêm ORDER BY positionvào truy vấn SQL của mình và vì bạn có thể dễ dàng chèn các mục vào giữa danh sách bằng cách lấy trung bình các giá trị của thành viên danh sách trước và sau, giả sử vị trí là số float chứ không phải là số nguyên.

Nên tránh sử dụng danh sách liên kết đôi, vì dễ vô tình làm cho các liên kết không nhất quán và kết thúc bằng một biểu đồ hoặc cây theo chu kỳ thay thế.

Tuy nhiên, API RESTful không gặp phải các hạn chế của cơ sở dữ liệu quan hệ. Bạn chỉ có thể làm một cái gì đó cảm thấy tự nhiên, thay vì sử dụng hack như một tài sản vị trí.

Nếu bạn chỉ có tối đa vài trăm thành phần trong danh sách, chỉ cần chuyển toàn bộ danh sách trong một yêu cầu. Giả sử chúng tôi muốn sắp xếp lại thứ tự [1, 2, 3, 4]các thành viên trong danh sách là ID, chúng tôi có thể

POST /url/of/the/list
Content-type: application/json
...

[1, 2, 4, 3]

Phần cuối có thể dịch phần này sang bất kỳ công nghệ cơ sở dữ liệu nào bạn đang sử dụng, nhưng người dùng API không phải xem xét các chi tiết này.

Nếu danh sách lớn và các mục thường sẽ được yêu cầu riêng lẻ, bạn có thể cho phép một chỉ mục trong url:

GET /page/7

Nếu bạn tham gia HATEOAS, phản hồi có thể bao gồm các liên kết trước / tiếp theo để điều hướng đơn giản, nếu tài nguyên thường được sử dụng như vậy. Tuy nhiên, điều này không có nghĩa là cơ sở dữ liệu của bạn cũng chứa danh sách liên kết đôi này.

Nếu danh sách rất lớn, bạn có thể muốn phơi bày các ArrayListhoạt động giống như / inserthoặc . Tôi có thể tưởng tượng một cuộc gọi nhưpushappend

POST /url/of/the/list?at=1357;mode=insert
...

description of the item to insert

Nếu sắp xếp lại là trường hợp sử dụng phổ biến và việc sắp xếp lại phải được cam kết ngay lập tức, thì bạn có thể đưa ra một điểm cuối thích hợp trong API của mình:

POST /url/of/the/list/reorder-item?from=783;to=1357

Nếu danh sách sắp xếp lại phải được cam kết rõ ràng, việc chuyển đơn hàng mới dưới dạng tài liệu JSON sẽ dễ dàng hơn, xem ở trên.

Bây giờ không hoàn toàn đúng khi bạn có thể xem API của mình tách biệt hoàn toàn với công nghệ cơ sở dữ liệu bạn đang sử dụng. Tuy nhiên, tốt nhất là giữ API bên ngoài càng miễn phí càng tốt từ các chi tiết triển khai. Nếu bất kỳ sắp xếp lại chạm vào khoảng 30 hàng chỉ để cập nhật một cột thứ tự số nguyên, đó không phải là vấn đề lớn. Chỉ cần làm điều đơn giản nhất có thể và luôn cập nhật toàn bộ danh sách. Nếu quy mô của bạn yêu cầu việc sử dụng cơ sở dữ liệu của bạn tinh vi hơn, hãy ưu tiên nắm bắt sự tinh tế này trong phần phụ trợ, nơi dễ duy trì tính nhất quán hơn.


1
Lưu ý rằng phương pháp "thay thế toàn bộ danh sách" có thể trở nên có vấn đề nếu có nhiều khách hàng thực hiện thay đổi. Nếu bạn không thực hiện bất kỳ biện pháp phòng ngừa nào, bạn có thể sẽ ghi đè lên những thay đổi của người khác ("cuối cùng để viết chiến thắng").
oefe

Các hoạt động giống như danh sách không nên có vấn đề này, miễn là các tham số (tại, từ, đến) là id, không phải là chỉ mục danh sách
oefe

2

Tôi nghĩ khả năng tồn tại của các phương pháp khác nhau phụ thuộc rất nhiều vào cơ sở dữ liệu cơ bản đang được sử dụng.

Cách tiếp cận này đề xuất để di chuyển một mục trong thứ tự:

POST / url / of / the / list / reorder-item? From = 783; to = 1357

Điều đó có thể phải tuân theo các điều kiện cuộc đua trừ khi bạn có giao dịch SERIALIZABLE. Mức READ_OMMITTED mặc định trong hầu hết các DB sẽ không loại bỏ điều kiện cuộc đua!

Tôi thực sự nghĩ rằng trong hầu hết các trường hợp - miễn là danh sách tương đối nhỏ - thì cách tiếp cận danh sách đầy đủ thay thế có ít vấn đề hơn với điều kiện chủng tộc và không thể làm hỏng dữ liệu. Nếu bộ vật phẩm đã thay đổi kể từ khi khách hàng đưa ra yêu cầu, bạn có thể trả lại 409 (Xung đột).

Nó chịu đựng những chiến thắng cuối cùng, nhưng điều đó đúng với BẤT K ap api. Bất kể API nào bạn đang triển khai, một khách hàng khác có thể đã cập nhật điều đó trong khi bạn đang xem một trang.

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.