【发布时间】:2015-05-15 08:36:50
【问题描述】:
我有几个客户,每个客户都由一个“租户”代表
我想知道将这个概念建模的最佳方法是什么。我做了很多研究,发现了这个话题:http://cassandra-user-incubator-apache-org.3065146.n2.nabble.com/Modeling-multi-tenanted-Cassandra-schema-td7591311.html
我知道有几种可能
- 租户一个键空间
- 租户一张表(列族)
- 一个字段代表所有表中的租户
我选择了解决方案 3,但我不确定是否有最佳架构以获得最佳性能
这是我的个人资料架构
CREATE TABLE profiles (
id timeuuid,
tenant text,
email text,
datasources set<text>,
info map<text, text>,
friends set<timeuuid>,
PRIMARY KEY(id, tenant)
);
CREATE INDEX ON profiles(datasources);
CREATE INDEX ON profiles(email);
我的 PARTITION KEY 是唯一性的“id”和 CLUSTERING KEY “tenant”。 我的需要是能够尽快执行此查询
SELECT * FROM profiles WHERE id = x
SELECT * FROM profiles WHERE tenant = x
SELECT * FROM profiles WHERE email = x
SELECT * FROM profiles WHERE datasources CONTAINS x
查询没问题,但我想知道将“租户”作为 PARTITION KEY 而不是“id”并使用“id”作为 CLUSTERING KEY 是否会更好
CREATE TABLE profiles (
...
PRIMARY KEY(tenant, id)
);
在我的应用程序中,“租户”始终是必填字段,因此以这种方式进行相同的查询不会有问题(但它是更快还是更慢?)
SELECT * FROM profiles WHERE tenant = y
SELECT * FROM profiles WHERE tenant = y AND id = x
SELECT * FROM profiles WHERE tenant = y AND email = x
SELECT * FROM profiles WHERE tenant = y AND datasources CONTAINS x
额外优势:能够按创建日期(ORDER BY id)对配置文件进行排序
如果我理解良好,使用租户作为 PARTITION KEY,Cassandra 会将同一租户的所有元素物理存储在同一行中,并且可能能够在该行中存储多达 20 亿条数据,在这种情况下,如果我的一位客户超过了这个数字?我还读到我们可以使用复合键,例如,将当前日期 (20150313) 放在键的第二部分,以便仅将租户当天的所有新配置文件分组在一行中
CREATE TABLE profiles (
...
date text,
PRIMARY KEY((tenant, date), id)
);
但使用此解决方案无法查询所有数据(查询中没有日期)。
您还可以在我的架构中看到,我将二级索引用于“电子邮件”和“数据源”字段。但是我在这里读到http://www.datastax.com/documentation/cql/3.1/cql/ddl/ddl_when_use_index_c.html 在返回少量结果的大表上使用二级索引(在我的情况下是一个)是一种不好的做法。在我的模式中,“数据源”是一个包含例如 facebookId、twitterId 等的集合
如果您有任何想法,我真的很感兴趣 :) !我是 Cassandra 的新手,如果有不懂的地方请告诉我
谢谢,
多诺万
【问题讨论】:
-
我正在考虑类似于选项 1 的东西,但每个租户都有一个应用程序列表,每个应用程序都有自己的密钥空间。你选择了哪个选项?您对这个选择满意吗?
-
我发现第一个选项的吸引力在于能够控制每个应用的复制。