使用索引的 Cassandra 帐户建模
Cassandra account modeling with indexes
我们正在使用社交登录在 cassandra 中为帐户 table 建模,我们选择电子邮件作为主键和瘦行实现。我们的 cassandra 版本为 2.1.6
。这是 table 定义:
CREATE TABLE account_by_email (
email_address text,
account_password text,
first_name text,
last_name text,
registered_at timestamp,
roles set<text>,
facebook_id text,
twitter_id text,
linkedin_id text,
password_reset_token blob,
password_reset_token_valid_until timestamp,
profile_image_url text,
PRIMARY KEY (email_address) ) WITH COMMENT='Accounts in system by email.';
这适用于电子邮件访问,因为当我们知道登录后的电子邮件地址时,我们可以快速访问每个帐户。
除了电子邮件登录选项外,用户还可以使用社交帐户登录/注册。当使用社交帐户登录时,流程是转到社交网络,接收社交 ID(facebook、twitter、linkedin)和电子邮件,并通过社交 id 查询帐户 table 以获得完整帐户或仅电子邮件并继续使用电子邮件每个 API 个请求。
我们目前在 facebook_id
、twitter_id
、linkedin_id
上添加了索引来支持这一点,因为我们处于一个节点的 MVP 阶段,并且我们选择 fats 实现而不是性能。
建模的正确方法是什么?以下是我们正在考虑的一些建议:
- 保留索引实施,因为通过社交 ID 获取仅在登录时发生一次(在使用该电子邮件之后)
- 每个社交 ID 都有一个 table,它将保存社交 ID 电子邮件对
- 每个社交 ID 都有一个 table,它将拥有完整的帐户(可以编辑帐户,这会增加更新的复杂性)
- 还有别的吗?
另一个问题是,当您对很少发生的访问路径建模时,具有高基数字段(如社交 ID)的索引实现真的那么糟糕吗?
我对此的看法如下:
创建一个帐户 table 来保存有关用户的所有信息,并使用 uuid 作为分区键:
CREATE TABLE account (
userid uuid,
first_name text,
last_name text,
registered_at timestamp,
roles set<text>,
password_reset_token blob,
password_reset_token_valid_until timestamp,
profile_image_url text,
PRIMARY KEY (userid) );
创建一个 table,link 将您的任何登录源添加到用户帐户:
CREATE TABLE account_by_login_source (
user_external_id text, // Can be an email address or a social network id
login_source text, // Can be any of "email", "facebook", "twitter",...
userid uuid,
account_password text, // only useful for email login, since you handle auth
PRIMARY KEY ((user_social_id, login_source)));
创建用户时,生成一个 uuid,在帐户 table 中插入一行,并在 account_login_source table.
中插入相应的行
这样,您的用户就可以使用多个登录源,并且 link 他们可以使用一个帐户。您只需 运行 2 个非常有效的查询即可让用户登录。
在不指定分区键的情况下使用二级索引肯定会出现问题,因为随着集群的增长,请求最终会超时。
如果您 运行 查询如下:
SELECT * FROM account_by_email where facebook_id = 'userid';
Cassandra 必须扫描集群中的每个节点,才能获得一行。
根据经验,我建议不要使用这种技术,一旦在生产中会导致很多绝望...
我们正在使用社交登录在 cassandra 中为帐户 table 建模,我们选择电子邮件作为主键和瘦行实现。我们的 cassandra 版本为 2.1.6
。这是 table 定义:
CREATE TABLE account_by_email (
email_address text,
account_password text,
first_name text,
last_name text,
registered_at timestamp,
roles set<text>,
facebook_id text,
twitter_id text,
linkedin_id text,
password_reset_token blob,
password_reset_token_valid_until timestamp,
profile_image_url text,
PRIMARY KEY (email_address) ) WITH COMMENT='Accounts in system by email.';
这适用于电子邮件访问,因为当我们知道登录后的电子邮件地址时,我们可以快速访问每个帐户。
除了电子邮件登录选项外,用户还可以使用社交帐户登录/注册。当使用社交帐户登录时,流程是转到社交网络,接收社交 ID(facebook、twitter、linkedin)和电子邮件,并通过社交 id 查询帐户 table 以获得完整帐户或仅电子邮件并继续使用电子邮件每个 API 个请求。
我们目前在 facebook_id
、twitter_id
、linkedin_id
上添加了索引来支持这一点,因为我们处于一个节点的 MVP 阶段,并且我们选择 fats 实现而不是性能。
建模的正确方法是什么?以下是我们正在考虑的一些建议:
- 保留索引实施,因为通过社交 ID 获取仅在登录时发生一次(在使用该电子邮件之后)
- 每个社交 ID 都有一个 table,它将保存社交 ID 电子邮件对
- 每个社交 ID 都有一个 table,它将拥有完整的帐户(可以编辑帐户,这会增加更新的复杂性)
- 还有别的吗?
另一个问题是,当您对很少发生的访问路径建模时,具有高基数字段(如社交 ID)的索引实现真的那么糟糕吗?
我对此的看法如下:
创建一个帐户 table 来保存有关用户的所有信息,并使用 uuid 作为分区键:
CREATE TABLE account (
userid uuid,
first_name text,
last_name text,
registered_at timestamp,
roles set<text>,
password_reset_token blob,
password_reset_token_valid_until timestamp,
profile_image_url text,
PRIMARY KEY (userid) );
创建一个 table,link 将您的任何登录源添加到用户帐户:
CREATE TABLE account_by_login_source (
user_external_id text, // Can be an email address or a social network id
login_source text, // Can be any of "email", "facebook", "twitter",...
userid uuid,
account_password text, // only useful for email login, since you handle auth
PRIMARY KEY ((user_social_id, login_source)));
创建用户时,生成一个 uuid,在帐户 table 中插入一行,并在 account_login_source table.
中插入相应的行这样,您的用户就可以使用多个登录源,并且 link 他们可以使用一个帐户。您只需 运行 2 个非常有效的查询即可让用户登录。
在不指定分区键的情况下使用二级索引肯定会出现问题,因为随着集群的增长,请求最终会超时。 如果您 运行 查询如下:
SELECT * FROM account_by_email where facebook_id = 'userid';
Cassandra 必须扫描集群中的每个节点,才能获得一行。 根据经验,我建议不要使用这种技术,一旦在生产中会导致很多绝望...