Citus多租户
数据库多租户
什么是多租户
多租户指一套系统能够支撑多个租户。一个租户通常是具有相似访问模式和权限的一组用户,典型的租户是同一个组织或者公司的若干用户。
权衡不同的多租户实现方式时,需要考虑如下因素:
扩展性:租户数量级别,以及未来发展趋势
安全性:租户之间数据隔离级别要求
资源共享:多租户通常有某种形式的资源共享
灵活性:不同租户可能有不同的需求,对特定租户需求的扩展能力
跨租户分析和优化:对全部租户或者多个租户的数据和行为进行分析的能力
运维和管理:运维管理的复杂度和便宜性,包括监控、修改数据库模式、创建索引、收集统计数据、数据加载等
成本:总体拥有成本,包括方案实现成本、运维成本等
多租户模型
一租户对应一数据库
最简单的多组户模型,为每一个用户创建一个数据库集群。
一租户对应一名字空间(模式)
多个租户共享同一个数据库,每个租户拥有独立的名字空间(或模式)。
全共享方式
不同租户共享同一个数据库、同一个名字空间。不同租户的数据在同一组表中共存,通过租户id标记和访问不同租户的数据
Citus采用此种多组户模型
Citus多租户用例
多组户应用中,通常的SQL都包含租户ID。
创建表
CREATE TABLE companies (
id bigint NOT NULL,
name text NOT NULL,
image_url text,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
CREATE TABLE campaigns (
id bigint NOT NULL,
company_id bigint NOT NULL,
name text NOT NULL,
cost_model text NOT NULL,
state text NOT NULL,
monthly_budget bigint,
blacklisted_site_urls text[],
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
CREATE TABLE ads (
id bigint NOT NULL,
company_id bigint NOT NULL,
campaign_id bigint NOT NULL,
name text NOT NULL,
image_url text,
target_url text,
impressions_count bigint DEFAULT 0,
clicks_count bigint DEFAULT 0,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
ALTER TABLE companies ADD PRIMARY KEY (id);
ALTER TABLE campaigns ADD PRIMARY KEY (id, company_id);
ALTER TABLE ads ADD PRIMARY KEY (id, company_id);
设置分发列
分发列设置非常重要
在此多组户模型中,我们使用公司id作为分发列或称为多组户的用户id
SELECT create_distributed_table('companies', 'id');
SELECT create_distributed_table('campaigns', 'company_id');
SELECT create_distributed_table('ads', 'company_id');
执行SQL
- 创建一个id为5000的租户
INSERT INTO companies VALUES (5000, 'New Company', 'https://randomurl/image.png', now(), now());
- 更新id为5的租户的数据
UPDATE campaigns
SET monthly_budget = monthly_budget*2
WHERE company_id = 5;
在事务中运行:
BEGIN;
DELETE from campaigns where id = 46 AND company_id = 5;
DELETE from ads where campaign_id = 46 AND company_id = 5;
COMMIT;
- 查询分析
- 简单查询
SELECT name, cost_model, state, monthly_budget
FROM campaigns
WHERE company_id = 5
ORDER BY monthly_budget DESC
LIMIT 10;
- 复杂查询
SELECT campaigns.id, campaigns.name, campaigns.monthly_budget,
sum(impressions_count) as total_impressions, sum(clicks_count) as total_clicks
FROM ads, campaigns
WHERE ads.company_id = campaigns.company_id
AND campaigns.company_id = 5
AND campaigns.state = 'running'
GROUP BY campaigns.id, campaigns.name, campaigns.monthly_budget
ORDER BY total_impressions, total_clicks;
[CitusDB中国]站主,PostgreSQL粉丝,现从事Citus研发工作
愿Citus在中国发展的越来越好
评论 (1)
liuhaifeng| 2019年9月25日
非常棒