Help us learn about your current experience with the documentation. Take the survey.

SQL 视图

概述

在 GitLab 中,我们使用 SQL 视图作为 PostgreSQL 系统目录(pg_* 表)的抽象层。这使得从 Rails 查询系统目录变得更加容易。

示例

例如,SQL 视图 postgres_sequencespg_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>

优势

使用这些视图有几个优势:

  1. ActiveRecord 集成:将复杂的 PostgreSQL 元数据查询封装在熟悉的 ActiveRecord 模型中
  2. 维护自动化:通过 Ruby 代码实现数据库维护任务的自动化
  3. 监控:简化数据库健康监控和指标收集
  4. 一致性:为数据库操作提供标准化接口

缺点

  1. 性能开销:由于访问时的物化和计算,视图可能会引入额外的查询开销。
  2. 调试复杂性:调试变得更加困难,因为你需要同时追踪 Ruby/Rails 层和 PostgreSQL 层。
  3. 迁移挑战:在模式迁移期间需要谨慎管理视图。如果底层表发生变化,你需要确保视图相应更新。Rails 迁移处理视图的方式不如处理常规表那么无缝。
  4. 维护开销:视图为数据库架构增加了另一层需要维护的编程语言。
  5. 测试复杂性:测试依赖视图的代码通常需要更多的测试设置。

指导原则

使用视图时,始终使用带有适当作用域和关系的 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

延伸阅读