나는 인보이스 및 지불에 대한 간단한 정규화 모델을 가지고 있습니다.Ruby on Rails에서 미 지불 금액에 denormaized 필드를 사용해야합니까?
관련 필드는 관계가
Invoice
has_many :invoice_payments
has_many :payments, through: :invoice_payments
InvoicePayment
belongs_to :invoice
belongs_to :payment
Payment
has_many :invoice_payments
has_many :invoices, through: :invoice_payments
있는 결제 모델이 질문에 관련이 없습니다하지만 같은 문제를 전시
invoices.id
invoices.amount_with_tax
invoice_payments.id
invoice_payments.invoice_id
invoice_payments.amount
있습니다.
변수 invoices
과 @invoices
은 ActiveRecord 관계입니다.
invoices.where('amount_outstanding > 0')
하지만 비정규 필드의 유지는 귀찮은입니다 : 내가 무급 청구서를 얻기 위해 송장 테이블에 코드를 amount_outstanding
필드를 추가하는 경우
은 간단하다. 해당 필드없이이를 얻을 수
내 현재 코드는 복잡하다 : 나는 여기에 대한 성능 테스트를 수행하지 않은
invoices = invoices.left_outer_joins(:invoice_payments)
invoices = invoices.distinct.select('invoices.*, sum(invoice_payments.amount) as total_payments')
invoices = invoices.group('invoices.id')
invoices = invoices.having('sum(invoice_payments.amount) < invoices.amount_with_tax or sum(invoice_payments.amount) is null')
하지만 많은있을 때 매우 좋은하지 않습니다 것 같습니다 시스템의 송장. ActiveRecord에 의해 생성 된 코드는 SQL에서 작성하는 코드와 비슷하므로 끔찍하지는 않습니다.
송장에 완전히 설명되지 않은 지불을 찾으려면 지불 측에서 유사한 코드가 필요합니다.
미결제 인보이스를 찾는 것은 미결제 금액을보고하는 것과 같이 빈번한 작업입니다. 잘 운영되는 회사의 경우 미수금 계정의 금액은 지급 된 금액보다 적습니다. 시간이 지남에 따라 전체 인보이스 중 훨씬 작은 비율이됩니다.
일반적으로 인보이스에 지불하는 것은 한 번만 수행되며 거의 되돌리거나 수정하지 않습니다. 대부분의 지불은 하나의 인보이스와 관련이 있으며 완전히 처리합니다.
또한 미지급 인보이스가 있는지 또는 해당 금액이 erb에 있는지 확인하려고 시도합니다. 예 : <%[email protected] %>
은 SQL 오류를 반환합니다.
개인적으로 비정규 화 된 데이터는 유지 보수 작업이 정규화 된 상태로 유지되는 작업의 약 3 배이기 때문에 개인적으로 비표준화 된 데이터가 마음에 들지 않습니다. 이 경우 amount_with_tax
이 변경되거나 InvoicePayment
이 편집되거나 삭제되거나 다른 송장으로 이동 된 경우 필드가 업데이트되어야합니다. amount_outstanding의 값을 계산하는 코드는 단 하나의 송장에 대한 매우 간단하다 : 나는 현재 amount_outstanding
을 유지하기 위해 송장에 콜백 및 InvoicePayments 모델을 사용하고
paid = invoice_payments.sum(:amount)
self.amount_outstanding = self.amount_with_tax - paid
save
.
그래서이 질문에 답할만한 가치가있는 비정규 화 된 필드가 있습니까? 아니면 이것을 달성하는 더 좋은 방법이 있습니까?
인보이스 업데이트에 대한 쿼리 빈도는 아마도 약 100 : 1입니다. 시스템의 최종 크기는 알 수 없지만 확장 기능을 제한하고 싶지는 않습니다. 전형적인 소규모 회사의 경우 1 년에 수천 통의 인보이스가있을 수 있지만별로 크지 않습니다. 정규화 된 코드는 카운트를 얻는 오류를 제외하고 실행되며 그에 대한 또 다른 쿼리를 작성할 수 있습니다. 조기 최적화에 대해서는 DK에 동의합니다. –
수천 개의 인보이스는 큰 수치가 아니므로 비정규 필드없이 시작하는 것이 더 좋은 옵션으로 보이고 필요에 따라 최적화 작업을 수행하십시오. 또한 카운트의 경우 코드를 작성하여 모델 또는 컨트롤러에서 카운트 한 다음 erb에 직접 코드를 작성하는 대신 erb에 값을 전달하는 것이 더 좋습니다. – coffeebytes