2012-11-30 33 views
5

Tôi có một Ruby on Rails ứng dụng với một cơ sở dữ liệu PostgreSQL trong đó có cấu trúc này:cơ sở dữ liệu theo chiều ngang rộng trong Ruby on Rails

class A < ActiveRecord::Base 
    has_many :B 
end 
class B < ActiveRecord::Base 
    has_many :C 
end 
class C < ActiveRecord::Base 
    attr_accessible :x, :y :z 
end 

Các chỉ là một vài A, và họ phát triển chậm (nói 5 tháng) . Mỗi A có hàng ngàn B, và mỗi B có hàng chục ngàn C (vì vậy mỗi A có hàng triệu C).

A là độc lập và B và C từ A khác nhau sẽ không bao giờ cần thiết cùng nhau (nghĩa là trong cùng một truy vấn).

Vấn đề của tôi là bây giờ tôi chỉ có một vài truy vấn A, ActiveRecord mất khá nhiều thời gian. Khi bảng cho C có hàng chục triệu hàng, truy vấn sẽ mất vĩnh viễn.

Tôi đang suy nghĩ về việc mở rộng quy mô cơ sở dữ liệu theo chiều ngang (nghĩa là bảng cho A, một bảng B và một bảng C cho mỗi A). Nhưng tôi không biết phải làm thế nào. Đó là một loại sharding tôi đoán, nhưng tôi không thể tìm ra cách để tạo ra các bảng DB động và sử dụng ActiveRecord để truy cập dữ liệu nếu bảng phụ thuộc vào đó một im làm việc với.

Cảm ơn bạn rất nhiều.

+1

Nếu bạn làm điều này, bạn có thể muốn phân vùng vào lược đồ khác nhau, do đó bạn không thực hiện một bảng kajillion trong 'công khai'. – tadman

+0

Cảm ơn bạn, tôi không biết về các lược đồ. Tuy nhiên, tôi sẽ làm điều đó như thế nào? – Nicolas

+0

Nếu tôi là bạn, tôi sẽ tìm kiếm một số loại tiện ích hoặc plugin cung cấp cho bạn một nơi để bắt đầu. Tôi không quen thuộc với không gian Postgres, nhưng có những thứ như [Octopus] (https://github.com/tchandy/octopus) có thể phục vụ như là một điểm nhảy. – tadman

Trả lời

2

Nếu bạn có mối quan tâm về hiệu suất chỉ với một vài hàng hoặc thậm chí với hàng triệu hàng, bạn cần phải lùi lại một bước trước khi cố gắng tạo ra một giải pháp cho bầu không khí. Vấn đề bạn đang mô tả rất dễ dàng được giải quyết bằng cách lập chỉ mục; không có lợi thế để tạo ra các bảng vật lý bổ sung và bạn sẽ giới thiệu sự phức tạp đáng kinh ngạc.

Như @ mu-quá-ngắn đã được nêu: hãy chú ý đến các kế hoạch truy vấn của bạn. Sử dụng công cụ của bạn để phân tích hiệu suất.

Điều đó được cho là bạn có thể sử dụng table partitioning để lưu trữ dữ liệu vào các bảng khác nhau, đặc biệt hữu ích cho dữ liệu phát triển rất nhanh nhưng chỉ hữu ích trong một khoảng thời gian nhất định (như một tháng). Bạn cũng có thể làm điều này với cột cờ lưu trữ bit để đưa các bản ghi cũ hoặc đã xóa vào bộ nhớ chậm hơn (nói RAID tiêu chuẩn bao gồm gỉ quay) trong khi vẫn giữ bản ghi hoạt động trên bộ nhớ nhanh hơn (như RAID của SSD).

+0

Cảm ơn bạn. Ý của bạn là gì khi bạn nói vấn đề được giải quyết bằng cách lập chỉ mục? Hiện tại C có một chỉ mục để liên kết chúng với B mà chúng thuộc về, và giống như của B đối với A. – Nicolas

+0

Nếu bạn có chỉ mục trên các bảng của mình, ngay cả một vài triệu hàng sẽ trả về tương đối nhanh, không bao giờ "khá dài" trừ khi bạn đang sử dụng phần cứng đã lỗi thời. Như một thử nghiệm sử dụng một công cụ như Navicat để chạy câu lệnh SQL mà bạn nghĩ là được thực hiện bởi ActiveRecord - nó thường không phải những gì bạn nghĩ - và xem cách so sánh với hiệu suất của AR như thế nào. Đuôi đăng nhập/development.log của bạn và xem liệu bạn có đang rơi vào con mồi đối với hiệu suất truy vấn N + 1 hay không (bằng cách vô tình loại trừ một phép nối). Tôi tò mò muốn biết loại yêu cầu trong quá trình nào cần hàng triệu hàng để hoạt động; Các hoạt động hàng MM + thường không thuộc về proc. – cfeduke

0

Vì vậy, có vẻ như bạn có cấu trúc giống cây. Nếu thực sự không cần phải kéo chúng ra khỏi cơ sở dữ liệu theo một cách nào đó, thì A của bạn có chính xác các thuộc tính của một "tài liệu", có một cái nhìn tại MongoDB. A sẽ được lưu với tất cả các B của họ và có C trong một kỷ lục duy nhất.

http://www.mongodb.org/

Nếu bạn đang tìm kiếm một ORM, kiểm tra

http://mongoid.org/en/mongoid/index.html

+0

Cảm ơn bạn! Tôi đã không nghĩ về NoSQL, có lẽ đó là những gì tôi đang tìm kiếm – Nicolas

+1

Có những mối quan tâm về ghi hiệu suất để lập kế hoạch đúng nếu bạn sử dụng Mongo, mặc dù kể từ 2.2 khóa toàn cầu đã biến mất (tôi chưa sử dụng nó kể từ 2.0) vì vậy có lẽ nó không tệ như trước đây. Bạn cũng sẽ cần phải xem xét dự phòng - 10gen đề xuất sáu máy ảo (trên các máy chủ vật lý khác nhau) tối thiểu cho một môi trường có quy mô và dự phòng. Đừng sợ làm mất chuẩn hóa dữ liệu của bạn - bạn có một trường hợp tốt để làm như vậy - trước khi thay đổi lưu trữ dữ liệu cơ bản của bạn. Ngoài ra PostgreSQL có Hstore là một thay thế NoSQL, mặc dù đòi hỏi phải nghiên cứu thêm để xem liệu nó có áp dụng được không. – cfeduke

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