2009-12-23 37 views
12

Tôi mới tham gia CouchDB và tìm hiểu về nó. Tôi đã không đi qua CouchDB hỗ trợ cho tính toàn vẹn tham chiếu. Chúng ta có thể tạo khóa ngoài cho một trường trong tài liệu CouchDB không?CouchDB có hỗ trợ tính toàn vẹn tham chiếu không?

Ví dụ: Có thể đảm bảo tên nhà cung cấp được sử dụng trong tài liệu đặt hàng có sẵn trong cơ sở dữ liệu của nhà cung cấp không?

CouchDB có hỗ trợ tính toàn vẹn tham chiếu không? Và có thể tạo một trường trong tài liệu là khóa chính không?

Trả lời

11

Không, CouchDB không thực hiện các khóa ngoại như vậy, vì vậy bạn không thể xử lý khóa toàn vẹn tham chiếu của hệ thống cho bạn. Bạn sẽ cần phải xử lý việc kiểm tra các nhà cung cấp ở cấp ứng dụng.

Để biết bạn có thể tạo trường là khóa chính hay không, khóa chính là trường _id, nhưng bạn có thể sử dụng bất kỳ json hợp lệ nào làm khóa cho các khung nhìn trên db. Vì vậy, ví dụ bạn có thể tạo ra một cái nhìn của các đơn đặt hàng với nhà cung cấp của họ như là chìa khóa.

cái gì đó như

function(doc) { 
    if (doc.type == 'order') 
    emit(doc.vendor,doc); 
} 

sẽ lấy tất cả các tài liệu trong cơ sở dữ liệu có một loại thuộc tính với thứ tự giá trị và thêm chúng vào một cái nhìn sử dụng nhà cung cấp của họ như là chìa khóa.

Intro to CouchDB views

8

Những câu hỏi này là cơ sở dữ liệu vô cùng quan hệ cụ thể.

Trong CouchDB hoặc bất kỳ RDBMS nào khác, bạn sẽ không lưu trữ dữ liệu giống như cách bạn làm trong RDBMS để thiết kế mối quan hệ theo cách này có thể không tốt nhất. Tuy nhiên, chỉ để cung cấp cho bạn ý tưởng về cách bạn có thể thực hiện việc này, hãy giả sử bạn có tài liệu cho nhà cung cấp và một loạt tài liệu cho các đơn đặt hàng cần "liên kết" trở lại tài liệu của nhà cung cấp.

Không có khóa chính, tài liệu nào có _id là uuid. Nếu bạn có một tài liệu cho một nhà cung cấp, và bạn đang tạo một tài liệu mới cho một thứ gì đó giống như một đơn đặt hàng, bạn có thể tham khảo các tài liệu của nhà cung cấp _id.

{"type":"order","vendor-id":"asd7d7f6ds76f7d7s"} 

Để tra cứu tất cả các đơn đặt hàng cho một nhà cung cấp cụ thể bạn sẽ có một cái gì đó xem bản đồ như:

function(doc) { if (doc.type == 'order') {emit(doc['vendor-id'], doc)}} 

Các _id tài liệu sẽ không thay đổi, do đó, "toàn vẹn" ở đó, ngay cả khi bạn thay đổi các thuộc tính khác trên tài liệu của nhà cung cấp như tên hoặc thông tin thanh toán của họ. Nếu bạn gắn tên nhà cung cấp hoặc các thuộc tính khác từ tài liệu của nhà cung cấp trực tiếp vào tài liệu đơn đặt hàng, bạn sẽ cần phải viết một tập lệnh nếu bạn muốn thay đổi chúng hàng loạt.

Hy vọng rằng sẽ giúp ích một chút.

+2

toàn vẹn tham chiếu là do-it-mình, nói cách khác. Lập trình viên phải nhớ tạo tài liệu nhà cung cấp trước, sau đó viết các mục tham chiếu đến ** _ id ** của nó, vì CouchDB không thể thực thi điều đó cho chúng. Tương tự, lập trình viên khi xóa phải nhớ bản thân trước hết phải xóa các đơn đặt hàng liên quan đến nhà cung cấp trước khi xóa nhà cung cấp - CouchDB sẽ không làm điều đó cho họ. Vì vậy, CouchDB sẽ cho phép bạn liên tục bước vào trạng thái không phù hợp; không có hỗ trợ để bảo vệ chống lại nó. –

+0

Tôi sẽ không gọi một tài liệu lúng túng mà không có tham chiếu đến nó là "trạng thái không nhất quán" vì tiểu bang trong trường hợp này là tài liệu tham khảo từ tài liệu khác sẽ bị xóa. Nhưng đặc điểm của bạn về ngữ nghĩa ở đây là chính xác. Tham chiếu chỉ là các chỉ mục và loại bỏ một tài liệu không suy ra một số giao dịch lớn hơn sẽ làm sạch tham chiếu ngược lại, mặc dù nó sẽ dọn sạch tham chiếu tới. – mikeal

+0

Quan trọng hơn, một máy chủ couchdb là REST-3 có khả năng (và bạn có thể xây dựng khả năng REST-4 nếu bạn muốn với các tài liệu thiết kế). Áp dụng thuật ngữ "tính toàn vẹn tham chiếu" sẽ không có ý nghĩa gì đối với cơ sở dữ liệu tài liệu hơn là cho một trò chơi video. Nó không phải là một cơ sở dữ liệu quan hệ và không giả vờ là. –

0

Trong khi không thể tạo ra một chế FK, có thể sử dụng Couch của Validate chức năng

function(newDoc, oldDoc, userCtx, secObj) { 
    if(newDoc && newDoc.type) switch(newDoc.type){ 
     case 'fish': 
      var allSpecies = ['trout','goldfish']; 
      if(!allSpecies.contains(newDoc.species)){ 
       throw({forbidden : 'fish must be of a know species'}); 
      } 
      break; 
     case 'mammals': 
      if(!['M','F'].contains(newDoc.sex)){ 
       throw({forbidden : 'mammals must have their sex listed'}); 
      } 
      break; 
    } 
} 

Bây giờ, nếu một người đã thực sự thông minh (Tôi không), họ có thể làm một cuộc gọi ra ngoài DB chính nó cho danh sách các loài ... đó sẽ là một khóa ngoại.

Bạn cũng có thể muốn đọc lên trên: How do I DRY up my CouchDB views?

Các vấn đề liên quan