Lõi trả lời
Cấu trúc bài viết của mình/đặt cho các tài liệu trong đó có lĩnh vực bạn muốn giữ độc đáo như sau:
Tạo một view. Trong chức năng bản đồ sử dụng trường bạn muốn thực thi duy nhất làm phím . Giá trị có thể là không có gì. Sử dụng hàm giảm để nhận số đếm cho mỗi khóa của bạn. Cách tốt nhất (để thực hiện) là sử dụng chức năng giảm chức năng được xây dựng trong _count.
Ngay sau khi bạn PUT/POST một tài liệu mới vào cơ sở dữ liệu, lấy lại id
và rev
nhóm và GET/yourdb/_design/yourapp/_view/viewname? = True & key =" giá trị -of-your-unique-field-from-step-1 ".
Nếu kết quả cuối cùng GET mang đến cho bạn một giá trị đếm khác hơn , sau đó bạn chỉ cần chèn một bản sao. Ngay lập tức DELETE/yourdb/id-from-step-2? Rev = rev-from-step-2.
Thư giãn.
Rough Ví dụ
phép nói rằng bạn đang lưu trữ các tài khoản người dùng và bạn muốn chắc chắn địa chỉ email là duy nhất, nhưng bạn không muốn làm cho nó id tài liệu (vì lý do gì). Tạo chế độ xem để nhanh chóng kiểm tra tính duy nhất trên địa chỉ email như được mô tả ở trên. Cho phép gọi nó là email. Nó có chức năng bản đồ có thể tương tự như vậy ...
function(doc) {
if(doc.type === 'account') {
emit(doc.email, 1);
}
}
Và chỉ _count
như giảm chức năng. Nếu bạn phát ra một số điện thoại như trên _sum
cũng sẽ hoạt động. Có và kiểm tra một lĩnh vực type
trên tài liệu của bạn như được hiển thị ở trên chỉ là một quy ước nhưng đôi khi tôi thấy nó hữu ích. Nếu tất cả các bạn đang lưu trữ là tài khoản người dùng, có thể bạn không cần điều đó.
Bây giờ cho phép nói rằng chúng ta đang chèn một tài liệu như vậy ...
POST /mydb/
{
"name": "Joe",
"email": "[email protected]"
}
Và CouchDB sẽ trả lời với một cái gì đó giống như ...
{
ok: true,
id: 7c5c249481f311e3ad9ae13f952f2d55,
rev: 1-442a0ec9af691a6b1690379996ccaba6
}
Kiểm tra để xem nếu bây giờ chúng tôi có hơn một [email protected] trong cơ sở dữ liệu ...
GET /mydb/_design/myapp/_view/emails/?group=true&key="[email protected]"
Và CouchDB sẽ trả lời bằng cái gì đó như ...
{
rows: [
{
key: "[email protected]",
value: 1
}
]
}
Nếu value
là bất cứ điều gì khác hơn là 1
trả lời rằng, có lẽ bạn muốn chèn một email trùng lặp. Vì vậy, xóa tài liệu và trả về lỗi dọc theo các dòng Địa chỉ email phải là duy nhất, tương tự như phản hồi cơ sở dữ liệu SQL điển hình hoặc bất kỳ điều gì bạn muốn.
Các delete sẽ đi một cái gì đó như thế này ...
DELETE /mydb/7c5c249481f311e3ad9ae13f952f2d55?rev=1-442a0ec9af691a6b1690379996ccaba6
ngắn Thảo luận (nếu bạn quan tâm)
Nếu bạn đang đến từ một tuổi * nền SQL tốt, điều này sẽ có vẻ sai và lạ. Trước khi bạn lật ra xem xét những điểm này. Có ràng buộc trên một trường, chẳng hạn như tính duy nhất hoặc bất kỳ điều gì khác, ngụ ý một lược đồ . CouchDB là schemaless. Đến từ * SQL có nghĩa là bạn sẽ phải thay đổi cách bạn nghĩ. ACID và Khóa không phải là cách duy nhất. CouchDB đi kèm với rất nhiều tính linh hoạt và sức mạnh. Làm thế nào bạn sử dụng để có được những gì bạn muốn là sẽ phụ thuộc vào các chi tiết của trường hợp sử dụng của bạn và làm thế nào bạn có thể thoát khỏi sự hạn chế của tư duy cơ sở dữ liệu quan hệ truyền thống.
Lý do tại sao đôi khi tôi thực hiện tính duy nhất theo cách này là bởi vì nó cảm thấy rất Couchy với tôi. Nếu bạn nghĩ về cách CouchDB làm việc với xử lý xung đột cập nhật, vv, cách tiếp cận này theo cùng một luồng. Chúng tôi lưu trữ tài liệu mà chúng tôi đưa ra, sau đó chúng tôi kiểm tra xem trường của chúng tôi là duy nhất hay không. Nếu không, hãy lấy tài liệu mà chúng ta vừa chèn vào bằng tay cầm thuận tiện mà chúng ta vẫn có trên đó, và làm một cái gì đó để giải quyết nhu cầu về tính duy nhất, chẳng hạn như xóa nó đi.
Bạn có thể bị cám dỗ trong ví dụ trên để kiểm tra tính duy nhất của địa chỉ email trước bạn POST
tài liệu. Hãy cẩn thận!!Nếu có nhiều điều xảy ra, có thể một tài liệu khác có cùng địa chỉ email có thể được chèn vào cơ sở dữ liệu ngay lập tức sau bạn kiểm tra xem email có tồn tại không, nhưng trước bạn làm POST
! Điều đó sẽ để lại cho bạn một email trùng lặp.
Không có gì sai khi đồng thời kiểm tra địa chỉ email trước khi bạn POST
. Ví dụ: đây là ý tưởng hay nếu người dùng của bạn điền vào biểu mẫu và bạn có thể ajax giá trị trường email ra khỏi cơ sở dữ liệu. Bạn có thể cảnh báo trước cho người dùng rằng địa chỉ email tồn tại hoặc ngăn gửi, v.v. Tuy nhiên, trong mọi trường hợp, bạn nên cũng luôn luôn kiểm tra tính duy nhất sau bạn POST
tài liệu. Sau đó phản ứng khi cần thiết. Từ quan điểm của phía giao diện người dùng, các bước ở trên sẽ trông không khác với kết quả thu được từ một cơ sở dữ liệu truyền thống * SQL puking trên một ràng buộc duy nhất.
Có thể xảy ra sự cố không? Vâng. Xem xét điều này. Giả sử [email protected] không tồn tại trong cơ sở dữ liệu. Hai tài liệu đến gần như cùng một lúc để được lưu vào cơ sở dữ liệu. Đốc A là POSTed
, sau đó Doc B là POSTed
nhưng trước khi chúng tôi có thể kiểm tra sự độc đáo cho Đốc APOST
. Vì vậy, bây giờ khi chúng tôi thực hiện kiểm tra tính duy nhất cho Doc APOST
, chúng tôi thấy rằng [email protected] có trong cơ sở dữ liệu hai lần. Vì vậy, chúng tôi sẽ xóa nó và báo cáo lại với vấn đề. Nhưng giả sử trước khi chúng tôi có thể xóa Doc A, kiểm tra tính duy nhất cho Doc B cũng xảy ra, nhận cùng một giá trị tính cho [email protected]. Bây giờ cả hai POSTs
sẽ bị từ chối, mặc dù [email protected] ban đầu không có trong cơ sở dữ liệu! Nói cách khác, nếu hai tài liệu có giá trị khớp vào ứng dụng của bạn gần như cùng một lúc, thì có thể là mà chúng có thể nhìn thấy lẫn nhau POSTs
và nhầm lẫn kết luận rằng giá trị mà chúng mang theo đã có trong cơ sở dữ liệu! Chúng tôi thực sự không thể ngăn chặn điều này vì không có kiểu RDB kiểu truyền thống nào đang khóa trong CouchDB. Nhưng để đổi lấy mức giá nhỏ đó, chúng ta có được sự sao chép chủ nhân và hàng tấn những thứ tuyệt vời khác. Tôi sẽ lấy nó! Và nếu đây là một vấn đề lớn đối với việc triển khai của bạn, bạn có thể thử giải quyết nó bằng cách thực hiện cơ chế thử lại một số loại, v.v.
Cuối cùng, CouchDB thực sự là một viên ngọc của cơ sở dữ liệu, nhưng không chỉ lấy nó và hy vọng nó sẽ là một phương pháp chống đạn. Rất nhiều thực sự sẽ phụ thuộc vào các chi tiết của ứng dụng cụ thể của bạn.
Vâng, đây là một giải pháp, nhưng cá nhân tôi thích khóa với Redis. Các giải pháp như vậy trông kỳ lạ khi các nhà phát triển đến từ thế giới RDBMS. CouchDB là khác nhau sau đó RDBMS, nhưng chúng ta nên từ chối tất cả các thực hành hiện có? Không có ACID và ổ khóa, nhưng không có tất cả những thứ này thì không thể thư giãn và chỉ viết các ứng dụng. CouchDB thiếu các tính năng chính và điều này thật đáng buồn. – Sam
Việc băm giá trị duy nhất trước khi thêm nó vào ID tài liệu giúp việc thêm giá trị có thể có các ký tự đặc biệt thuận tiện hơn. –
Lưu ý rằng nếu bạn có kế hoạch giữ cho mọi thứ thân thiện với nhiều người, điểm 2.sẽ ** không ** thất bại trừ khi khóa đã tồn tại trên nút * current *. Các khóa chỉ là duy nhất trên nút mà chúng tồn tại. Hãy xem câu trả lời của Raffi M. cho một giải pháp thân thiện với cụm đơn giản cho vấn đề này. – user1973386