2008-11-11 23 views
5

Giả giản đồ dữ liệu sau:Có thể có một khóa ngoài hợp chất trong đường ray không?

Usage 
====== 
client_id 
resource 
type 
amount 

Billing 
====== 
client_id 
usage_resource 
usage_type 
rate 

Trong ví dụ này, giả sử tôi có nhiều nguồn lực, mỗi trong số đó có thể được sử dụng trong nhiều cách khác nhau. Ví dụ: một tài nguyên là widget. Widgets có thể là foo ed và có thể là bar ed. Gizmo s cũng có thể là foo ed và bar ed. Các loại hình sử dụng này được lập hóa đơn ở các mức giá khác nhau, thậm chí có thể là các mức giá khác nhau cho các khách hàng khác nhau. Mỗi lần xuất hiện của một mức sử dụng (của tài nguyên) được ghi lại trong bảng Sử dụng. Mỗi tỷ lệ thanh toán (cho kết hợp khách hàng, tài nguyên và loại) được lưu trữ trong bảng thanh toán.

(Bằng cách này, nếu sơ đồ dữ liệu này không phải là cách đúng đắn để tiếp cận vấn đề này, xin vui lòng đóng góp ý kiến.)

Có thể, sử dụng Ruby on Rails và ActiveRecord, để tạo ra một mối quan hệ has_many từ Billings to Usages để tôi có thể nhận danh sách các trường hợp sử dụng cho một tỷ lệ thanh toán nhất định? Có cú pháp của số has_many, :through mà tôi không biết?

Một lần nữa, tôi có thể tiếp cận vấn đề này từ góc độ sai, vì vậy nếu bạn có thể nghĩ ra một cách tốt hơn, hãy lên tiếng!

Trả lời

6

Rõ ràng là một dự án tại sourceforge để mở rộng ActiveRecord của Rails với sự hỗ trợ cho Composite Primary Keys. Tôi đã không sử dụng phần mở rộng này, nhưng nó có thể giúp bạn. Nó cũng là một viên ngọc tại rubyforge.

Đồng bằng Ruby on Rails, kể từ phiên bản 2.0, không hỗ trợ các khóa chính phức hợp (xem HowToUseLegacySchemas). Mỗi bảng phải có một khóa tự động một cột, có tên là "id".

Giải thích tôi đã thấy là: "Bạn chỉ cần ghép các khóa chính nếu bạn muốn sử dụng cơ sở dữ liệu cũ." Đây tất nhiên là một cái nhìn vô lý dốt nát về mô hình hóa dữ liệu.

Các giải pháp tôi thấy sẽ là:

  • Usage.client_id -> Client.id
  • Usage.type_id -> Usagetype.id
  • Usage.resource_id -> Resource.id
  • Billing.usage_id -> Usage.id
  • Billing.client_id -> Client.id
  • Billing.type_id -> Usagetype.id
  • Billing.resource_id -> Resource.id

Các phím nước ngoài dường như dư thừa trong Billing nỗ lực để thực thi toàn vẹn tham chiếu cục bộ. Nhưng nó không hoàn toàn đạt được điều đó - nó không ngăn bạn tạo hàng trong Billing tham chiếu một hàng trong Usage với kết hợp máy khách/tài nguyên/usagetype sai, không khớp với hàng trong hàng tham chiếu trong bảng Thanh toán.

chỉnh sửa: @Yarik: vâng, bạn nói đúng. Điều này có ý nghĩa hơn đối với Usage để tham chiếu Billing.

  • Usage.billing_id -> Billing.id

Hmm. Tôi đã tạo một biểu đồ ER nhưng tôi đang gặp sự cố khi chèn nó làm hình ảnh.

+0

Chờ một giây ... Không nên nó là khác cách xung quanh - một khóa chính trong Thanh toán và khóa ngoài trong Cách sử dụng ?? – Yarik

+0

Câu trả lời hay, nền tảng tốt. Quan điểm của RoR về cơ sở dữ liệu dường như có vấn đề với tôi. Nhưng các dbms dường như đã chính xác trả thù của nó bằng cách gánh chịu RoR với một danh tiếng như là một cơ sở dữ liệu chậm, không thể đánh giá cao. – dkretz

1

Bạn có thể tạo bất kỳ ràng buộc nào bạn muốn bằng lệnh 'thực thi' trong quá trình di chuyển.

Có thể bạn sẽ muốn thêm một số xử lý lỗi vào .save để xử lý các trường hợp khi ràng buộc phát sinh lỗi.

Bạn không thể sử dụng máy phát điện phương pháp tích hợp AR để tạo ra các tập quán ra khỏi thanh toán, nhưng bạn vẫn có thể có phương pháp:

class Billing 
    def usages 
    Usage.find(:all, :conditions => ["x = ? and y = ?", self.x, self.y]) 
    end 
end 
Các vấn đề liên quan