2012-06-19 22 views
21

Tôi sắp xây dựng Node.js tôi/bày tỏ/mongoose/hộ chiếu ứng dụng và tôi đang suy nghĩ về quyền schema thiết kế cho người dùng và tài khoản.MongoDB thiết kế giản đồ cho nhiều người sử dụng auth chiếm

Sẽ có người dùng đăng nhập từ twitter và facebook cũng như từ tài khoản gốc. Ở giai đoạn sau, tôi muốn một người dùng kết nối cả twitter và facebook với ứng dụng của tôi (và thậm chí có thể nhiều tài khoản bên ngoài hơn).

Tôi không thể nghĩ ra giải pháp tốt cho tình huống đó. Dưới đây là các tùy chọn tôi đang nghĩ đến:

1.Lưu mô hình hồ sơ và mô hình tài khoản. Tài liệu hồ sơ đại diện cho người dùng duy nhất, trong khi tài khoản cung cấp tên người dùng và mật khẩu (tài khoản nội bộ) hoặc dữ liệu xác thực từ nhà cung cấp xác thực (tài khoản bên ngoài). Tiểu sử phải có ít nhất một tài liệu tài khoản lồng nhau.

var ExtAccountSchema = new Schema({ 
    type: String, // eg. twitter, facebook, native 
    uid: String 
}); 

var IntAccountSchema = new Schema({ 
    username: String, 
    password: String 
}); 

var ProfileSchema = new Schema({ 
    firstname: String, 
    lastname: String, 
    email: String, 
    accounts: [Account] // Pushing all the accounts in there 
}); 

Những gì tôi không thích về nó là những tài liệu tài khoản không quá phù hợp phát sinh từ dữ liệu tài khoản khác nhau và thực tế là tôi có một thời gian khó khăn khi tìm đúng tài khoản khi người dùng đăng nhập của tôi trong (tìm kiếm uids và các loại tài khoản trong lồng tài liệu -.-)

2.Having tất cả dữ liệu trong một mô hình đơn

var ProfileSchema = new Schema({ 
    firstname: String, 
    lastname: String, 
    email: String,   
    twitter-uid: String, 
    facebook-uid: String 
    password: String 
}); 

Vâng đây chỉ là xấu xí -.- nó có thể được dễ dàng hơn/nhanh hơn để tìm ra dữ liệu tài khoản đúng, nhưng nó không phải tốt với ma intain.

Có giải pháp nào tốt hơn không? Có cách nào tốt nhất không?

+0

Không giống như các cơ sở dữ liệu quan hệ, với MongoDB, thiết kế lược đồ tốt nhất phụ thuộc rất nhiều vào cách bạn sẽ truy cập dữ liệu. Bạn sẽ sử dụng dữ liệu Tài khoản nào và bạn sẽ truy cập vào dữ liệu đó bằng cách nào? –

+0

Tôi sẽ sử dụng dữ liệu tài khoản để xác thực với hộ chiếu. Dữ liệu hồ sơ sẽ được truy cập trên hầu hết các trang trên các mục đích đa dạng. Tôi sẽ truy cập thông qua mongoose ODM – Sven

+0

Vì vậy, dữ liệu tài khoản sẽ chỉ được truy cập khi người dùng đăng nhập và bạn sẽ sử dụng cơ chế phiên để theo dõi thông tin đăng nhập khi điều đó xảy ra? (Trái ngược với việc cần dữ liệu Tài khoản trên mọi truy cập trang.) –

Trả lời

39

1) Có ba chiến lược mà bạn có thể mất đến cấu trúc dữ liệu của bạn trong MongoDB:

  • a) Mảng các văn bản nhúng
  • b) Mảng tài liệu tham khảo nhúng
  • c) Mở rộng thành tài liệu gốc

Chiến lược (a) là tài liệu đầu tiên bạn mô tả, trong đó tài liệu Tiểu sử chứa một mảng Tài liệu phụ tài khoản.

Chiến lược (b) tương tự như chiến lược (a), nhưng bạn sẽ sử dụng một mảng tham chiếu đến các tài liệu khác (thường trong bộ sưu tập Tài khoản) thay vì nhúng tài liệu thực.

Chiến lược (c) là mô tả bạn mô tả là "có tất cả dữ liệu trong một mô hình duy nhất".

2) Thường được coi là Phương pháp hay nhất để sử dụng một loạt tài liệu được nhúng, đặc biệt nếu thông tin trong chúng có thể thay đổi. Nếu nó sẽ làm cho cuộc sống của bạn dễ dàng hơn, bạn có thể sử dụng một chìa khóa để phân biệt các loại tài khoản, như vậy:

{ 
    firstname: 'Fred', 
    lastname: 'Rogers', 
    email: '[email protected]', 

    accounts: [ 
      { kind: 'facebook', 
       uid: 'fred.rogers' 
      }, 
      { kind: 'internal', 
       username: 'frogers', 
       password: '5d41402abc4b2a76b9719d911017c592' 
      }, 
      { kind: 'twitter', 
       uid: 'fredr' 
      } 
      ] 
    } 

3) MongoDB cho phép bạn tìm kiếm trên một tài liệu nhúng.Vì vậy, bạn sẽ viết các truy vấn sau đây (cú pháp JavaScript):

db.profile.find( 
     { email: '[email protected]', 'accounts.kind': 'facebook' } 
     ); 

Với chỉ số thích hợp, truy vấn này sẽ là khá nhanh.

+0

Câu trả lời hay được viết :-) Cảm ơn bạn. Tôi đã nghĩ về điều đó nhưng không biết làm thế nào để làm điều đó. Tôi sẽ cho nhiều hơn một điểm nếu tôi có thể. Cảm ơn một lần nữa. – Sven

+0

Tôi có đúng trong giả sử tôi nên sử dụng các chỉ mục hỗn hợp-thưa thớt không? 'ProfileSchema.index ({accounts.kind, accounts.uid}, {unique: true, sparse: true});'? – CheapSteaks

+0

Bạn không nên ** sử dụng các chỉ mục phức tạp. Chỉ số phức tạp-thưa thớt hầu như luôn luôn không làm những gì bạn muốn. Hãy mở một chủ đề mới cho việc này. –

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