2009-10-07 68 views
7

Tôi có một ứng dụng sử dụng cấu trúc tùy chỉnh đồ thị (giống cây). Các cấu trúc không phải là cây thực sự, nhưng khá nhiều thứ được kết nối với nhau. Số lượng dữ liệu cũng lớn (hàng triệu nút có thể tồn tại). Các nút cây có thể thay đổi theo loại để làm cho nó thú vị hơn (thừa kế). Tôi không muốn thay đổi cấu trúc dữ liệu để chứa dung lượng lưu trữ lâu dài.Dữ liệu đồ thị có sẵn (Java)

Tôi muốn lưu giữ dữ liệu này mà không cần thêm quá nhiều công việc. Tôi đã goggled một số tùy chọn để giải quyết vấn đề này, nhưng không thể tìm thấy bất cứ điều gì phù hợp chính xác cho nhu cầu của tôi. Có thể lựa chọn: serialization, cơ sở dữ liệu với ORM (Hibernate?), JCR (JackRabbit?), Bất cứ điều gì khác?

Hiệu suất là quan trọng, bởi vì nó là một ứng dụng "thời gian thực" dựa trên GUI (không xử lý theo lô) và có thể có hàng triệu nút đồ thị cần đọc và ghi giữa bộ nhớ và lưu trữ dữ liệu.

Có ai có kinh nghiệm hoặc ý tưởng về việc lưu trữ các loại dữ liệu này không?

+0

tôi nghi ngờ quá chung chung của nó để cung cấp cho một câu trả lời tốt - bạn có thể phác thảo một số trường hợp sử dụng cho cấu trúc cây? tức là, nó sẽ được sử dụng như thế nào, lưu trữ của nó (nếu có thể nói). Để thực hiện, bạn có thể muốn nói thời gian truy cập thông thường nhanh như thế nào trong millis hoặc một số đơn vị khác, bởi vì chỉ nói hiệu suất và "thời gian thực" khá mơ hồ. – Chii

+0

Khi "tất cả mọi thứ được kết nối với nhau", nó không phải là một cây, nó là một đồ thị: http://en.wikipedia.org/wiki/Graph_%28data_structure%29 Có lẽ bạn nên rephrase tiêu đề? – nawroth

+0

Bộ sưu tập tốt các cơ sở dữ liệu đồ thị hiệu suất cao hiện tại: http://java.dzone.com/news/most-trendy-graph-databases – AMilassin

Trả lời

5

Theo dữ liệu của bạn sử dụng một cấu trúc dữ liệu đồ thị (về cơ bản: nút và các cạnh/các mối quan hệ), một cơ sở dữ liệu đồ thị sẽ là một trận đấu rất tốt. Xem câu trả lời của tôi trên The Next-gen Databases cho một số liên kết. Tôi là một phần của dự án cơ sở dữ liệu đồ thị mã nguồn mở Neo4j, xem this thread để thảo luận về nó. Một lợi thế lớn của việc sử dụng Neo4j trong một trường hợp như của bạn là không có vấn đề gì trong việc theo dõi sự bền bỉ/kích hoạt các đối tượng hoặc độ sâu kích hoạt và tương tự. Có thể bạn sẽ không cần phải thay đổi cấu trúc dữ liệu trong ứng dụng của mình, nhưng dĩ nhiên một số mã bổ sung sẽ là cần thiết. Design guide đưa ra một ví dụ về cách mã của bạn có thể tương tác với cơ sở dữ liệu.

2

Vì bạn cho biết rằng có một lượng lớn dữ liệu, bạn có thể muốn có một cơ chế mà bạn có thể dễ dàng mang dữ liệu khi cần. Serialization có lẽ không phải là rất dễ dàng để xử lý với số lượng lớn dữ liệu. Để chia nhỏ thành các phần có thể quản lý, bạn sẽ cần phải sử dụng các tệp riêng biệt trên đĩa hoặc lưu trữ chúng ở nơi khác. JCR (JackRabbit) là một hệ thống quản lý nội dung. Những người làm việc tốt cho các đối tượng kiểu 'tài liệu'. Có vẻ như những mảnh riêng lẻ của cây bạn muốn lưu trữ có thể nhỏ nhưng cùng nhau chúng có thể lớn. Đó không phải là ý tưởng của một CMS.

Tùy chọn khác mà bạn đề cập, ORM, có lẽ là lựa chọn tốt nhất của bạn tại đây. JPA (Java Persistence API) là một công cụ tuyệt vời để thực hiện ORM trong Java. Bạn có thể viết cho đặc tả JPA và sử dụng Hibernate, Eclipselink hoặc bất kỳ hương vị nào khác của nhà cung cấp tháng. Những người sẽ làm việc với bất cứ cơ sở dữ liệu bạn muốn. http://java.sun.com/javaee/5/docs/api/index.html?javax/persistence/package-summary.html

Lợi ích khác của JPA là bạn có thể sử dụng số FetchType lười biếng để tải phụ thuộc vào cây. Bằng cách này, ứng dụng của bạn chỉ cần tải tập hợp các phần hiện tại đang hoạt động. Như những thứ khác là cần thiết, lớp JPA có thể lấy chúng từ cơ sở dữ liệu khi cần thiết.

1

Một ORM, ví dụ sử dụng JPA api (Hibernate, EclipseLink, ...) có thể sẽ làm cho nó rất nhanh chóng để thực hiện sự kiên trì. Hiệu suất nguyên của toàn bộ độ bền vững của cây có xu hướng phức tạp để đạt được so với JDBC đơn giản. Vì vậy, nếu tiêu chí hiệu suất duy nhất của bạn là bền vững toàn bộ cây trong một cảnh, đó có lẽ không phải là lựa chọn tốt nhất.
Mặt khác, nếu bạn cũng cần tải cây, đồng bộ hóa các thay đổi của cây, thì JPA cung cấp các tính năng được tích hợp sẵn (sau một chút tinh chỉnh) hiệu suất tốt hơn so với thực hiện thủ công.

Việc tuần tự hóa trong java có xu hướng khá chậm và tạo ra rất nhiều dữ liệu. Tuần tự hóa cũng khá dễ vỡ khi bạn thay đổi lớp trong ứng dụng của bạn và hoàn toàn vô dụng nếu bạn cần đồng bộ hóa các thay đổi của cây.

Trong cùng danh mục như tuần tự hóa, bạn có thể tuần tự hóa trong XML và lưu giữ nó trong một số cơ sở dữ liệu XML (Oracle XDB). Tuy nhiên, những thiết bị này được thiết kế linh hoạt hơn cho lưu trữ/truy vấn hơn tốc độ thô.

Nếu thời gian không phải là một mối quan tâm, cách tốt nhất là luôn luôn liên quan đến một DBA có thẩm quyền và thiết kế một datamodel tối ưu và tái cấu trúc cây cho phù hợp.

2

Tôi có gần như vấn đề chính xác và được sử dụng ngủ đông. Chúng tôi đã gặp rất nhiều vấn đề ở cuối dự án vì quan điểm cơ bản đã buộc toàn bộ biểu đồ vào bộ nhớ ngay cả khi sử dụng các loại tìm nạp lười biếng.Những công cụ này là tốt vào đầu mặc dù bởi vì chúng tôi có thể nhanh chóng có được một tầng DB tại chỗ đã cho chúng tôi một cái gì đó (huzzah nhanh nhẹn). Chỉ khi chúng tôi tiến hành cải tiến hiệu suất, chúng tôi mới nhận ra rằng chúng tôi cần phải viết một lớp kiên trì thông minh hơn.

Có thể thực hiện một số xử lý trước trên dữ liệu của bạn không? Nếu vấn đề là tương tự, có rất nhiều giá trị trong việc cố gắng biến đổi dữ liệu thành một biểu mẫu trung gian gần với khung nhìn của bạn hơn so với tên miền gốc và lưu trữ nó trong DB. Bạn luôn có thể liên kết ngược lại nguồn gốc bằng cách sử dụng loại tìm nạp lười.

Về cơ bản chúng tôi sử dụng một hệ thống 4 tầng: Tên miền DB, ViewModel-DB lai (pre-xử lý lớp), ViewModel, Xem

Ưu điểm của bước này trước khi chế biến (đặc biệt là với thời gian thực giao diện người dùng), là bạn có thể trang dữ liệu vào ViewModel và hiển thị nó độc đáo. Vì vậy, nhiều hiệu suất trong một ứng dụng thời gian thực là nhẹ của bàn tay, chỉ cần ở lại đáp ứng và cho họ thấy một cái gì đó tốt đẹp trong khi họ chờ đợi. Trong trường hợp của chúng tôi, chúng tôi có thể hiển thị vùng hộp dữ liệu 3d đang phân trang, dữ liệu được liên kết với dữ liệu tải có thể hiển thị chỉ báo trực quan. Hybrid ViewModel-DB cũng có thể làm những việc tốt đẹp như hàng đợi LRU phù hợp với dữ liệu miền của chúng tôi. Lợi thế lớn nhất mặc dù là để loại bỏ các liên kết trực tiếp. Các nút có nội dung nào đó tương tự với URL với dữ liệu được liên kết của chúng. Khi kết xuất, chúng tôi có thể hiển thị liên kết hoặc hiển thị liên kết mà chúng tôi đang phân trang vào lúc này.

Độ bền ở cấp DB là JPA (Hibernate) để bắt đầu, nhưng cuối cùng các bảng mà nó tạo ra cho cấu trúc thừa kế của chúng tôi là khủng khiếp và khó duy trì. Cuối cùng, chúng tôi muốn kiểm soát nhiều hơn các bảng được JPA cho phép (hoặc ít nhất là được phép). Đây là một quyết định khó khăn vì JPA đã làm cho rất nhiều lớp DB dễ dàng. Kể từ khi JPA giữ mọi thứ tốt đẹp và POJO nó không yêu cầu mucking xung quanh với các kiểu dữ liệu của chúng tôi. Vì vậy, điều này là tốt đẹp.

Tôi hy vọng có cái gì đó bạn có thể kéo ra khỏi câu trả lời vòng vo này, và may mắn :)

1

xem xét lưu trữ các nút của bạn trong một cơ sở dữ liệu, một sơ đồ thích hợp có thể là:

t1(node_id,child_id) 
t2(node_id,data1,data2,..,datan) 

sau đó sử dụng JDBC để truy cập/sửa đổi dữ liệu. nếu bạn sử dụng các chỉ mục thích hợp, nó sẽ thực hiện khá tốt lên đến quy mô khoảng 100 triệu bản ghi. cảm giác ruột của tôi là để tránh serialization đối tượng chung nếu hiệu suất là thực sự quan trọng bởi vì bạn mất một số kiểm soát các đặc tính hiệu suất của mã với những giải pháp.

nếu bạn cần hiệu suất tốt hơn, bạn có thể sử dụng lớp memcached.

0

Tôi tin rằng giải pháp cho vấn đề của bạn là sử dụng Terracotta làm cơ chế lưu trữ liên tục của bạn. Tôi khuyến khích bạn đọc this excellent article về việc đó.

Nó giải quyết hai mối quan tâm chính của bạn: hiệu suấtminh bạch.Nó dễ dàng mở rộng lên các đồ thị lớn, trong khi vẫn duy trì hiệu suất cao, vì cơ chế đồng bộ hiệu quả của nó chỉ gửi các sự khác biệt trên mạng. Nó cũng lưu giữ đồ thị của bạn một cách minh bạch bởi vì nó hoạt động ở mức VM, giải phóng bạn về vấn đề không phù hợp trở kháng mà bạn sẽ phải đối mặt với các lựa chọn được đề cập trong các câu trả lời khác (ORM hoặc OCM).

Để rõ ràng, Đất nung là không phải là giải pháp kiên trì cho mọi trường hợp. Nó được sử dụng tốt nhất khi bạn cần dữ liệu có sẵn trên các lần khởi động lại máy và bạn cần nó một cách nhanh chóng. Nó không phải là một giải pháp tốt khi bạn cần dữ liệu đó "lưu trữ", ví dụ như có yêu cầu để truy cập dữ liệu đó lâu sau khi hệ thống đang chạy đã ngừng hoạt động với nó. Hãy suy nghĩ về đơn đặt hàng vào cửa hàng trực tuyến. Bạn có thể muốn lưu trữ các đơn đặt hàng này trong nhiều năm sau khi chúng được hoàn thành. Trong những trường hợp này, bạn có thể xem xét phương pháp lai, nơi dữ liệu được chọn cần được lưu trữ có thể được kéo ra khỏi cụm Terracotta và được lưu trữ bằng RDBMS truyền thống.

Để có đánh giá đầy đủ hơn về các ưu điểm & nhược điểm, hãy nhớ đọc this StackOverflow post bao gồm nhiều chi tiết hơn trong việc lựa chọn.

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