Help us learn about your current experience with the documentation. Take the survey.
SQL 视图
概述
在 GitLab 中,我们使用 SQL 视图作为 PostgreSQL 系统目录(pg_* 表)的抽象层。这使得从 Rails 查询系统目录变得更加容易。
示例
例如,SQL 视图 postgres_sequences 是 pg_sequence 和其他 pg_* 表的抽象层。它使用以下 Rails 模型进行查询:
module Gitlab
module Database
# Backed by the postgres_sequences view
class PostgresSequence < SharedModel
self.primary_key = :seq_name
scope :by_table_name, ->(table_name) { where(table_name: table_name) }
scope :by_col_name, ->(col_name) { where(col_name: col_name) }
end
end
end这使我们能够通过 Ruby 代码管理数据库维护任务:
Gitlab::Database::PostgresSequence.by_table_name('web_hook_logs')
=> #<Gitlab::Database::PostgresSequence:0x0000000301a1d7a0
seq_name: "web_hook_logs_id_seq",
table_name: "web_hook_logs",
col_name: "id",
seq_max: 9223372036854775807,
seq_min: 1,
seq_start: 1>优势
使用这些视图有几个优势:
- ActiveRecord 集成:将复杂的 PostgreSQL 元数据查询封装在熟悉的 ActiveRecord 模型中
- 维护自动化:通过 Ruby 代码实现数据库维护任务的自动化
- 监控:简化数据库健康监控和指标收集
- 一致性:为数据库操作提供标准化接口
缺点
- 性能开销:由于访问时的物化和计算,视图可能会引入额外的查询开销。
- 调试复杂性:调试变得更加困难,因为你需要同时追踪 Ruby/Rails 层和 PostgreSQL 层。
- 迁移挑战:在模式迁移期间需要谨慎管理视图。如果底层表发生变化,你需要确保视图相应更新。Rails 迁移处理视图的方式不如处理常规表那么无缝。
- 维护开销:视图为数据库架构增加了另一层需要维护的编程语言。
- 测试复杂性:测试依赖视图的代码通常需要更多的测试设置。
指导原则
使用视图时,始终使用带有适当作用域和关系的 ActiveRecord 模型,而不是原始 SQL 查询。视图在设计上是只读的。添加新视图时,确保有适当的迁移、模型、测试和文档。
测试
测试视图时,使用 swapout_view_for_table 辅助函数临时将视图替换为表。
这样你就可以使用工厂创建与视图返回的记录相似的记录。
RSpec.describe Gitlab::Database::PostgresSequence do
include Database::DatabaseHelpers
before do
swapout_view_for_table(:postgres_sequences, connection: ApplicationRecord.connection)
end
end