ruby-on-rails - 在 Rails 中存储到数据库之前透明地压缩属性

标签 ruby-on-rails database postgresql compression

我的一个模型有一个巨大的文本列,我想在将它存储到数据库之前对其进行压缩(不是为了节省磁盘空间,而是因为我不想通过网络从我的数据库服务器到我的应用程序服务器)

如果相关的话,我的数据库是 postgresql

这是我尝试编写的扩展,但由于某种原因,这在生产中不起作用(实际存储在数据库中的数据看起来像十六进制(例如“34bee1c2d099ba21da3ac533d5f99cda2654feb73985430df39c5ffd8fbf9d9ff3aa9392d5a5”而不是 Zlib 输出(例如“xD\x\xF2Oy=\x9C\x7F5\xE9\xC44\x01M\")。不确定发生了什么

module HasCompressedAttributes
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def has_compressed_attributes(*fields)
      fields.each do |field|
        define_method(:"#{field}=") do |uncompressed|
          write_attribute(:"#{field}", Zlib::Deflate.deflate(uncompressed))
        end

        define_method(:"#{field}") do
          Zlib::Inflate.inflate(read_attribute(:"#{field}")) rescue nil
        end
      end
    end
  end
end

ActiveRecord::Base.class_eval{ include HasCompressedAttributes }

这里有更好的方法吗?也许是现有的 gem ?

最佳答案

bytea 在最新版本的 PostgreSQL 中默认的编码方式是 "hex" :

The "hex" format encodes binary data as 2 hexadecimal digits per byte, most significant nibble first. The entire string is preceded by the sequence \x (to distinguish it from the escape format).

所以您在数据库中看到的 34bee1c2d099ba21da3ac... 内容只是十六进制编码的二进制数据。如果您使用的是 bytea 列(即创建列时的 t.binary)而不是 text,AR 应该为您编码和解码这些内容varchar(即 t.textt.string)。如果您要将二进制数据存储在数据库中,那么您必须使用 t.binary 这样您就不能将这种魔法完全隐藏在模块中,还必须正确设置架构.

关于ruby-on-rails - 在 Rails 中存储到数据库之前透明地压缩属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9242938/

相关文章:

ruby-on-rails - 如何在 Rails 6 中选择要删除的多个项目(通过复选框)

php - 我将如何插入影响多个表的值?

postgresql - 如何使用 docker-compose 连接到 PostgreSQL?

sql - PostgreSQL 和队列命令

与 View 连接的 PostgreSQL 查询性能不佳

ruby-on-rails - 事件管理安装错误

ruby-on-rails - 使用 RSpec 测试 Rails 3 respond_with

html - rails grouped_collection_select 'options' 可以设置样式吗?

database - 通过站点到站点 VPN 将 Azure 网站连接到本地数据库

java - 没有 SQL 服务器的数据库持久性