2011-02-28 45 views
9

Tôi vẫn đang học các bài học về mô hình hóa dữ liệu trong bigtable/nosql và sẽ đánh giá cao một số phản hồi. Sẽ công bằng khi nói rằng tôi nên tránh các mối quan hệ cha mẹ -> con trong mô hình dữ liệu của tôi nếu tôi thường xuyên phải đối phó với các trẻ em trong tổng thể qua các bậc cha mẹ?parent-> mối quan hệ con trong appengine python (bigtable)

Ví dụ: giả sử tôi đang xây dựng một blog sẽ được đóng góp bởi một số tác giả và mỗi người có bài đăng và mỗi bài đăng có thẻ. Vì vậy, tôi có khả năng có thể thiết lập một cái gì đó như thế này:

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    owner = db.ReferenceProperty(Author, 
    collection_name='posts') 
    tags = db.StringListProperty() 

Vì tôi hiểu điều này sẽ tạo một nhóm thực thể dựa trên cha mẹ Tác giả. Điều này có gây ra sự kém hiệu quả nếu tôi chủ yếu cần truy vấn Bài đăng theo các thẻ mà tôi muốn cắt ngang qua nhiều Tác giả không?

Tôi hiểu việc thực hiện truy vấn trên các thuộc tính danh sách có thể không hiệu quả. Giả sử mỗi bài đăng có khoảng 3 thẻ trung bình, nhưng có thể đi hết mức tối đa 7. Và tôi hy vọng bộ sưu tập các thẻ có thể của tôi sẽ ở mức thấp. Có bất kỳ lợi ích nào để thay đổi mô hình đó thành một cái gì đó như thế này không?

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    owner = db.ReferenceProperty(Author, 
    collection_name='posts') 
    tags = db.ListProperty(db.Key) 

class Tag(db.Model): 
    name = db.StringProperty() 

Hoặc tôi có nên làm điều gì đó như thế này?

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    owner = db.ReferenceProperty(Author, 
    collection_name='posts') 

class Tag(db.Model): 
    name = db.StringProperty() 

class PostTag(db.Model): 
    post = db.ReferenceProperty(Post, 
    collection_name='posts') 
    tag = db.ReferenceProperty(Tag, 
    collection_name='tags') 

Và câu hỏi cuối cùng ... nếu trường hợp sử dụng phổ biến nhất của tôi sẽ truy vấn bài đăng bằng nhiều thẻ. Ví dụ: "tìm tất cả bài đăng có thẻ trong {'táo', 'cam', 'dưa chuột', 'xe đạp'}" Là một trong những phương pháp tiếp cận phù hợp hơn cho truy vấn tìm các bài đăng có bất kỳ bộ sưu tập thẻ nào ?

Cảm ơn, tôi biết đó là một ngụm. :-)

+0

Không có ví dụ nào của bạn tạo nhóm tổ chức. Trong ví dụ đầu tiên, bạn đang sử dụng một ReferenceProperty, nó tạo ra một tham chiếu đến thực thể kia - điều này có thể thay đổi và không ngụ ý quyền sở hữu. Tham chiếu gốc được tạo bằng cách chỉ định đối số 'cha' cho hàm tạo cho thực thể - xem trang này để biết chi tiết: http://code.google.com/appengine/docs/python/datastore/entities.html#Entity_Groups_and_Ancestor_Paths –

+0

Ah, cảm ơn Nick. Tôi đã bỏ lỡ một phần ... nghĩ rằng đó là các tài liệu tham khảo đã tạo ra mối quan hệ cha mẹ và đã mất tích mà bạn cần phải vượt qua cha mẹ để các nhà xây dựng. Điều đó có ý nghĩa bây giờ. –

Trả lời

5

Điều gì đó giống như cách tiếp cận đầu tiên hoặc thứ hai rất phù hợp với App Engine.Hãy xem xét các thiết lập sau:

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    author = db.ReferenceProperty(Author, 
    collection_name='posts') 
    tags = db.StringListProperty() 

class Tag(db.Model): 
    post_count = db.IntegerProperty() 

Nếu bạn sử dụng thẻ chuỗi (trường hợp bình thường) như KEY_NAME Tag tổ chức nào, bạn có hiệu quả có thể truy vấn cho bài viết với một từ khóa cụ thể, hoặc liệt kê các thẻ của một bưu điện, hoặc lấy thống kê thẻ:

post = Post(author=some_author, tags=['app-engine', 'google', 'python']) 
post_key = post.put() 
# call some method to increment post counts... 
increment_tag_post_counts(post_key) 

# get posts with a given tag: 
matching_posts = Post.all().filter('tags =', 'google').fetch(100) 
# or, two tags: 
matching_posts = Post.all().filter('tags =', 'google').filter('tags =', 'python').fetch(100) 

# get tag list from a post: 
tag_stats = Tag.get_by_key_name(post.tags) 

Cách tiếp cận thứ ba yêu cầu thêm truy vấn hoặc tìm nạp cho hầu hết các hoạt động cơ bản và sẽ khó khăn hơn nếu bạn muốn truy vấn nhiều thẻ.

+0

tuyệt vời, cảm ơn robert. đây thực sự là cách tôi viết nó. nhưng tôi vẫn còn mới, vì vậy tôi đã không chắc chắn nếu điều này thực sự là cách tốt nhất, vì vậy tôi đánh giá cao bạn chia sẻ kinh nghiệm của bạn! –

+1

@Bob Ralian, một điều cần thận trọng là các chỉ mục đang bùng nổ. Khái niệm chung là tốt; bạn cũng có thể tìm thấy mẫu "Chỉ số quan hệ" hữu ích, nhưng vì danh sách của bạn rất nhỏ _and_ bạn muốn các thẻ bạn không cần một thực thể riêng biệt. (http://www.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html) –

2

Tôi sẽ chọn phương pháp cuối cùng, vì nó cho phép truy xuất danh sách bài đăng trực tiếp được cấp thẻ.

Cách tiếp cận đầu tiên về cơ bản khiến không thể giữ một bộ thẻ chuẩn tắc. Nói cách khác, câu hỏi "những thẻ hiện đang có mặt trong hệ thống" là rất tốn kém để trả lời.

Cách tiếp cận thứ hai khắc phục sự cố đó, nhưng như tôi đã đề cập không giúp bạn truy xuất bài đăng được cung cấp thẻ.

Nhóm thực thể có chút quái thú, nhưng đủ để nói cách tiếp cận đầu tiên KHÔNG tạo nhóm thực thể và chỉ cần thiết cho hoạt động cơ sở dữ liệu giao dịch và đôi khi hữu ích cho việc đọc dữ liệu được tối ưu hóa, nhưng có lẽ không cần thiết trong một ứng dụng nhỏ.

Cần lưu ý rằng mọi cách tiếp cận bạn thực hiện sẽ chỉ hoạt động tốt cùng với chiến lược bộ nhớ đệm thông minh. Ứng dụng GAE TÌNH YÊU caching. Hãy thân mật với api memcache và tìm hiểu các hoạt động đọc/ghi hàng loạt trên memcache và kho dữ liệu.

+0

Cảm ơn Triptych. Tôi thực sự không lo lắng về vấn đề kinh điển, vì tôi sẽ xử lý trong quá trình xác nhận trước khi lưu. Re: nhóm thực thể, các tài liệu nói "Để tạo một thực thể trong một nhóm, bạn tuyên bố rằng một thực thể khác là cha mẹ của thực thể mới khi bạn tạo nó." Vì vậy, tôi lấy điều đó để có nghĩa là một mối quan hệ cha mẹ-> con sẽ tạo ra một nhóm thực thể nếu nó được khai báo trên đứa trẻ tại thời điểm nó được tạo ra. Tôi hiểu điểm của các nhóm thực thể dành cho các giao dịch. Nhưng chúng có gây ra độ trễ/không hiệu quả cho các lựa chọn trên các nhóm thực thể không? Có thể giao dịch nhóm chéo không? –

+0

Giao dịch nhóm chéo là không thể, nhưng nếu bạn đang thực hiện nhiều lựa chọn trên các nhóm tổ chức, đó là dấu hiệu mềm cho thấy bạn không nên sử dụng chúng. Ngoài ra, hãy hiểu rằng quá trình xác thực của bạn sẽ yêu cầu đọc mọi thẻ trong mỗi mô hình Đăng trong kho dữ liệu, nếu sử dụng cách tiếp cận đầu tiên. – Triptych

+0

Tôi sẽ có một mô hình Thẻ riêng biệt bất kể. Và tôi sẽ giữ nó trong memcache. Cách tiếp cận đầu tiên thực sự không liên quan đến họ nhưng thay vào đó, họ sẽ sử dụng chúng để đọc các chuỗi có thể chấp nhận được. Nó không nhất thiết phải phù hợp với Bài đăng mà tôi sẽ chọn theo thẻ, nhưng sẽ thích hợp hơn cho những thứ như tùy chọn Reader, nơi tôi chỉ cần kéo danh sách các thẻ. –

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