我正在用cassandra为用户创建一个表。用户拥有唯一的user_id
和唯一的display_name
。
我的表目前类似于:
create table user (user_id text primary key,
display_name text,
joined timestamp,
last_seen timestamp,
...);
当新用户创建帐户时,我需要检查他们输入的显示名称是否已经是别人的。我能做到这一点的最快方法是什么?
这个项目对我来说主要是一个学习项目,我想在半现实世界的情况下尝试一些NoSQL概念。
我自己的想法是使用两个这样的表:
create table user (user_id text primary key,
display_name text,
joined timestamp,
last_seen timestamp,
...);
create table user_by_display_name (display_name text primary key, user_id text);
然后在user_by_display_name
中查找是否存在用户名将比查找user where display_name = ?
更快。这是正确的假设吗?
我觉得主键上的两次查找user_by_display_name where display_name = ?
然后使用user_id
中的user
进行另一次查找可能比单user where display_name = ?
次查找慢,如果我需要有关该用户的信息。
答案 0 :(得分:0)
您的假设是正确的,您将需要按照描述进行非规范化。首先设计查询然后构建表。
你的桌子应该是
CREATE TABLE users (
user_id text,
display_name text,
last_seen timestamp,
PRIMARY KEY(user_id)
WITH ...);
CREATE TABLE users_by_display_name (
display_name text,
user_id text,
last_seen timestamp,
PRIMARY KEY(display_name);
这样你就可以进行1次查找。写入便宜,读取费用昂贵。尽可能避免读取。也就是说,您的分区是1行,您在Key值数据库中进行查找。你的第二个选择也不会非常昂贵。
您可以按照描述创建第二个表。根据您正在运行的cassandra版本,您还可以从用户表中创建MATERIALIZED VIEW
以实现相同的查找。如果您经常更新last_seen属性,因为他们会在更新行时删除这些内容,因此您不想使用这些内容。所以可能只限于display->userId
。
一旦进行了查找设置,您仍然需要担心两个用户窃取相同用户名的竞争条件。在这种情况下,您可能会考虑轻量级交易。也就是说,你想避免经常这样做,因为它们很贵。
然而,LWT确实遇到了一些问题,比如他们不是"真的"事务并且它们比标准读/写慢。只要确保你知道自己得到了什么。