我目前正在开发一个 Rails 7 应用程序,该应用程序大量利用 PostgreSQL 的
JSONB
数据类型来存储大量非结构化数据。当我寻求优化读写操作时,我特别有兴趣了解索引和查询这些字段的最佳实践。这是我当前如何处理 JSONB
数据的简单示例:
class User < ApplicationRecord
# Users table has a JSONB column named :properties
end
# Querying JSONB data
User.where("properties @> ?", {notifications: true}.to_json)
所以:
JSONB
列建立索引以提高性能的最佳实践是什么?ActiveRecord
中实现了自定义范围或方法
充分利用 PostgreSQL 的 JSONB
功能来获得更多
复杂的查询?JSONB
是否与以前的版本有显着不同?我正在寻找可以提高性能的见解或优化,尤其是对于复杂的查询。任何建议或代码片段将不胜感激!
在
gin
列上使用 jsonb
索引可有效搜索 jsonb 文档中出现的键或键/值对。
CREATE INDEX idx_properties ON users USING GIN (properties);
或者作为 Rails 迁移
class AddIndexToUsers < ActiveRecord::Migration
def change
add_index :users, :properties, using: :gin
end
end
如果您想要与特定键对应的值的特定索引,也可以创建表达式索引。
CREATE INDEX idx_properties ON users ((properties->>'notifications'));
或者作为 Rails 迁移
class AddIndexToUsers < ActiveRecord::Migration
def change
add_index :users, "(properties->>'notifications')"
end
end
即使它处于维护模式,我也使用 jsonb_accessor gem 取得了很多成功。它支持:
将 jsonb 支持的字段作为 ActiveRecord 模型的一等公民输入
和
它还添加了用于查询 jsonb 列的通用范围。
gem 做了很多事情,因此请查看 README 以获取支持功能的完整详细说明,但这里是一个开箱即用的一些常见功能的简单示例。
class User < ApplicationRecord
# notifications and email now behave similar to normal attributes
jsonb_accessor :properties, notifications: :boolean, email: :string
validates :notifications, presence: true
validates :email, presence: true, uniqueness: true
scope :with_notifications, -> { properties_where(notifications: true) }
def notifications_enabled?
notifications == true
end
end
User.jsonb_where(:properties, notifications: true)
User.jsonb_where_not(:properties, notifications: true)
# or alternatively
User.properties_where(notifications: true)
User.properties_where_not(notifications: true)