如何在Ruby on Rails中查询数据库表字节大小?附实践与最佳实践疑问
关于最佳实践的解答
对于商业应用而言,两种方式都有适用场景,但更普遍的做法是通过应用外工具监控数据库指标:
- 应用外方式:借助云服务商(比如Heroku自带的PostgreSQL监控面板)、数据库原生监控工具(如PostgreSQL的
pg_stat_statements扩展),或是第三方监控平台(如Datadog、New Relic)来跟踪数据库大小、增长速率、连接数、查询性能等核心指标。这种方式无需侵入应用代码,能获取更全面的监控数据,还可设置自动告警,更适合生产环境的长期运维。 - 应用内方式:一般作为补充手段,用于特定业务场景——比如需要在内部管理后台给运维人员快速展示核心业务表的大小,或是结合业务逻辑做自定义阈值告警。但这种方式需要额外开发维护,仅能覆盖有限指标,通常不会作为主要监控方案。
你的方案在个人项目中完全可行,实现简单且能满足需求;如果是商业应用,建议优先采用应用外监控,再根据实际需求考虑是否在应用内添加这类展示功能。
我的环境版本:
- Ruby 3.2.2
- Rails 7.1.2
- PSQL 15(对应gem为pg 1.1)
实现方案
我需要在管理后台展示各数据库表的预估大小,方便判断何时升级按行数和大小计费的Heroku PSQL插件,网上未找到直接解决方案,因此自己实现了以下代码:
将代码放入所有模型继承的基类ApplicationRecord中:
class ApplicationRecord < ActiveRecord::Base primary_abstract_class def self.total_db_size query = <<-SQL.squish SELECT pg_size_pretty( pg_database_size(#{"'#{ActiveRecord::Base.connection_db_config.database}'"}) ) AS size SQL connection.execute(query).first["size"] end def self.total_relation_size query = <<-SQL.squish SELECT pg_size_pretty( pg_total_relation_size(#{"'#{name.underscore.pluralize}'"}) ) AS size SQL find_by_sql(query).first.size end end
注意事项:
- 从
ApplicationRecord及其子类调用total_db_size,返回结果一致; - 从
ApplicationRecord直接调用total_relation_size会报错,必须从具体模型调用。
示例用法
数据库大小
irb(main):001> ApplicationRecord.total_db_size (1.4ms) SELECT pg_size_pretty( pg_database_size('famifin_development') ) AS size => "8269 kB"
表大小——必须从模型调用
irb(main):002> ApplicationRecord.total_relation_size ApplicationRecord Load (1.4ms) SELECT pg_size_pretty( pg_total_relation_size('application_records') ) AS size ...PG::UndefinedTable: ERROR: relation "application_records" does not exist (ActiveRecord::StatementInvalid)...
irb(main):003> User.total_relation_size User Load (0.7ms) SELECT pg_size_pretty( pg_total_relation_size('users') ) AS size => "48 kB"
内容的提问来源于stack exchange,提问作者Luke Loera
相关产品推荐
相关产品推荐

