Rails中如何对Lockbox加密的amount字段实现求和操作
加密字段求和解决方案
问题原因
PG::UndefinedColumn: ERROR: column "amount" does not exist报错是因为你调用的sum(:amount)属于数据库层聚合方法,会直接调用PostgreSQL原生SUM函数。但Lockbox加密的amount字段明文不会存储在数据库中,仅存在加密后的amount_ciphertext密文字段,数据库无法直接识别amount字段。
修复方案
因为密文只能在应用层解密后再做计算,需要把原来的数据库层sum改为Ruby应用层求和:
# transaction_controller.rb @one_month_transactions_sum = transactions.where(transaction_date: 1.month.ago..Date.today) .sum(&:amount) .abs
sum(&:amount)会先加载所有符合条件的交易记录,调用Lockbox封装的amount属性方法自动解密密文,再对返回的明文数值做累加。
注意事项
- 若单月交易数据量较大(万级以上),全量加载会产生较高内存开销,建议用分批加载的方式求和:
# 分批求和避免内存溢出,每次加载1000条 @one_month_transactions_sum = 0 transactions.where(transaction_date: 1.month.ago..Date.today).find_each(batch_size: 1000) do |transaction| @one_month_transactions_sum += transaction.amount end @one_month_transactions_sum = @one_month_transactions_sum.abs
- 如果业务侧频繁需要对加密字段做聚合运算,可在符合数据安全合规要求的前提下,新增加密衍生字段用于统计,避免每次查询都加载全量数据。
内容的提问来源于stack exchange,提问作者Nick Seferos
相关产品推荐
相关产品推荐

