世界上最伟大的投资就是投资自己的教育
PostgreSQL 的模式 Schema (十)
1. Schema
PostgreSQL-schemas这里介绍了 Schema 的概念和用法。
简而言之,Schema 是一种命名空间,它可以用来隔离表,隔离数据,又避免了连接多个数据库。在同一个数据库下,不同的 Schema 可以有相同名字的表 (table),每个数据库默认都有 public 这个 Schema,还可以对 Schema 进行权限的限制等。对 Schema 的操作也很简单,比如,创建CREATE SCHEMA myschema;
、DROP SCHEMA myschema;
,要对 Schema 下的表进行操作只需要加上前缀就好了。比如,CREATE TABLE public.products ( ... );
。
还有个比较重要的东西要说,那就是 search_path。它是表的搜索路径,相当于 linux 系统的 $PATH 变量,找可执行程序的,不过它是找表的,一般来说,找表可以加 Schema,如果不加就找 search_path 指定的 Schema,查看 search_path 可以用SHOW search_path;
,而使用SET search_path TO myschema,public;
可以更改搜索路径。
Schema 特别适合于以下几种场合。
- 管理员管理自己所属分公司的数据。
- 隔离不同幼儿园的数据。
其实acts_as_tenant就可以实现类似上面的效果,不过 acts_as_tenant 相对简单,只是代码级加上少量数据级的控制,而 Schema 就是数据库级别的真正数据隔离,也是原生支持,所以更好,不过只支持 PostgreSQL 数据库。
2. multi-tenancy
我们使用apartment这个 gem 来实现多 Schema 的系统,也叫做 multi-tenancy。
2.1 安装
添加下面这一行到 Gemfile 文件。
gem 'apartment'
生成配置文件 config/initializers/apartment.rb。
bundle exec rails generate apartment:install
2.2 创建新的 Tenants
使用 ruby 代码来创建 PostgreSQL Schema 是这样的。在rails console
中执行下面这行。
Apartment::Tenant.create('tenant_name')
执行这行命令会有很多输出,其实它首先会创建一个 PostgreSQL Schema 叫 tenant_name,然后会把以前的表也在这个叫 tenant_name 的 Schema 下生成一遍。
我们来验证一下。用rails db
进入数据库。
执行\dn
来查看所有的 Schema。
rails365_pro=# \dn
List of schemas
Name | Owner
-------------+----------
public | postgres
tenant_name | postgres
(2 rows)
使用\dt
来查看所有 tenant_name 下的表 (table)。
rails365_pro=# \dt tenant_name.*;
List of relations
Schema | Name | Type | Owner
-------------+----------------------+-------+----------
tenant_name | admin_exception_logs | table | postgres
tenant_name | articles | table | postgres
tenant_name | friendly_id_slugs | table | postgres
tenant_name | groups | table | postgres
tenant_name | photos | table | postgres
tenant_name | schema_migrations | table | postgres
tenant_name | taggings | table | postgres
tenant_name | tags | table | postgres
(9 rows)
有 Apartment::Tenant.create 这个命令,结合数据库维护起整个 Schema 就很灵活了,比如,School.create
的时候也顺便Apartment::Tenant.create :school
。
2.3 切换 Tenants
Schema 避免了连接不同的数据库,但也是要切换默认的 Tenants。使用Apartment::Tenant.switch!
。
# 先切换到public下查看数据
Apartment::Tenant.switch!('public')
Article.all
# 切换到tenant_name下验证数据
Apartment::Tenant.switch!('tenant_name')
Article.all
有create
命令和switch!
命令,结合起来再灵活地配合 application_controller.rb 等文件就可以很好地实现 multi-tenancy 系统了。原理就是先用create
创建好 Schema,然后到查数据或资源地方switch!
,切换到正确的 Schema 来查就好,而这个可以用 controller 中的 before_action 之类的方法搞定,设定一个当前的 tenant 即可。怎么来设定当前的 tenant,那就可以结合传过来的参数或子域名等来处理了。
2.4 删除 Tenants
有创建就有删除的,那就是 drop,用这个命令可以来维护 Schema。
Apartment::Tenant.drop('tenant_name')
2.5 通过子域名来切换 Tenants
默认情况下,是通过子域名来切换 Tenants 的,这个可以通过配置文件config/initializers/apartment.rb
查看到。
require 'apartment/elevators/subdomain'
Rails.application.config.middleware.use 'Apartment::Elevators::Subdomain'
意思就是,假如是 foo.example.com,就会切换到 foo 这个 Schema,如果是 bar.example.com,就会切换到 bar 这个 Schema,是这个 gem 提供的功能,是自动切换的,如果不需要这个功能也可以注释掉上面两行代码即可。
更加详细的功能可以看apartment的 github 官方 readme 文档或查看其源码。
完结。
本站文章均为原创内容,如需转载请注明出处,谢谢。
© 汕尾市求知科技有限公司 | Rails365 Gitlab | 知乎 | b 站 | csdn
粤公网安备 44152102000088号 | 粤ICP备19038915号
Top