使用 Cassandra 的内部网络应用程序数据模型
Internal network application data model with Cassandra
我正在设计一个应用程序,该应用程序将使用户能够发送请求以相互联系,查看他们发送或接收的请求,在他们的交互过程中做笔记以供以后连接时参考,以及从他们的联系人中删除用户列出。
在 RDBMS 中,架构将是:
table 列为
的用户
- uid(每个用户的唯一字符串)
table 请求列:
来自 - 用户 id
to - 用户id主键(from,to)
已创建 - 时间戳
消息 - 字符串
过期 - 时间戳
table 与列的连接:
来自 - 用户 id
至-用户id
主键(从,到)
注释-字符串
已创建 - 时间戳
已修改 - 时间戳
isFavourite - 是来自用户的最爱,值 0 或 1
isActive - 软删除,值为 0 或 1
pairedConnection - 显示 to 和 from 之间的连接是否已停用(to 用户从其联系人列表中删除了 from 用户),值 0 或 1
我预计需要的查询是:
查找用户发送的请求
查找某个用户收到的请求
查找给定用户的所有活动联系人
找到一个用户的所有收藏夹
找到所有从他们的列表中删除给定用户的用户
更新一个用户在遇到另一个与他有联系的用户时所做的笔记
将用户更新为最爱
将连接标记为软删除
我正在尝试在 Cassandra 中对此进行建模,但对为实现最高效率而选择的键感到困惑。
到目前为止,我有以下想法,欢迎更多有经验的Cassandra用户反馈:
create table users(
uid text PRIMARY KEY
);
create table requestsByFrom(
from text,
to text,
message text,
created timestamp,
expiry timestamp,
PRIMARY KEY (from,to)
create table requestsByTo(
from text,
to text,
message text,
created timestamp,
expiry timestamp,
PRIMARY KEY (to,from)
);
create table connections(
from text,
to text,
notes text,
created timestamp,
modified timestamp,
isFavourite boolean,
isActive boolean,
pairedConnection boolean,
PRIMARY KEY (from,to)
);
create table activeConnections(
from text,
to text,
isActive boolean,
PRIMARY KEY (from,isActive)
);
create table favouriteConnections(
from text,
to text,
isFavourite boolean,
PRIMARY KEY (from, isFavourite)
);
create table pairedConnection(
from text,
to text,
pairedConnection boolean,
PRIMARY KEY ((from,to), pairedConnection)
);
Cassandra 具有与 RDBMS 不同的范例,这一点在必须完成数据建模的方式上更为明显。您需要记住,首选非规范化,并且您会有重复的数据。
table的定义应该是基于查询来检索数据的,这在问题的定义中有部分说明,例如:
find the sent requests for a user
采用 table requestsByFrom
的初始设计,另一种选择是
CREATE TABLE IF NOT EXISTS requests_sent_by_user(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
message TEXT,
created TIMESTAMP
PRIMARY KEY (requester_email, recipient_email)
) WITH default_time_to_live = 864000;
注意from
是一个限制关键字,expiry
信息可以通过default_time_to_live子句(TTL)的定义来设置,它会在定义的时间后删除记录;此值为插入记录后的秒数,示例为 10 天(864,000 秒)。
主键建议是邮箱地址,也可以是UUID,名字不推荐,因为可以多人同名(如James Smith
)或同一个人名字可以有多种写法(下面的例子Jim Smith
、J. Smith
和j smith
可能指的是同一个人)
名称 recipient_name
也已添加,因为您很可能希望显示它;应添加任何其他将 displayed/used 与查询一起使用的信息。
find the received requests for a user
CREATE TABLE IF NOT EXISTS requests_received_by_user(
recipient_email TEXT,
requester_email TEXT,
requester_name TEXT,
message TEXT,
created TIMESTAMP
PRIMARY KEY (recipient_email, requester_email)
) WITH default_time_to_live = 864000;
最好使用batch同时向requests_sent_by_user
和requests_received_by_user
添加记录,这将确保两者之间信息的一致性table s,TTL(数据到期)也将相同。
storing contacts
题中有4个table连接:connections
、active_connections
、favourite_connections
、paired_connections
,两者有什么区别他们?他们会有不同的 rules/use 案例吗?如果是这样的话,将它们设置为不同的 tables:
是有意义的
CREATE TABLE IF NOT EXISTS connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
notes TEXT,
created TIMESTAMP,
last_update TIMESTAMP,
is_favourite BOOLEAN,
is_active BOOLEAN,
is_paired BOOLEAN,
PRIMARY KEY (requester_email, recipient_email)
);
CREATE TABLE IF NOT EXISTS active_connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
last_update TIMESTAMP,
PRIMARY KEY (requester_email, recipient_email)
);
CREATE TABLE IF NOT EXISTS favourite_connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
last_update TIMESTAMP,
PRIMARY KEY (requester_email, recipient_email)
);
CREATE TABLE IF NOT EXISTS paired_connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
last_update TIMESTAMP,
PRIMARY KEY (requester_email, recipient_email)
);
注意去掉了boolean flag,逻辑是如果记录存在于active_connections
,会认为是活动连接
当一个新的连接被创建时,它可能在不同的tables中有几条记录;捆绑所有这些插入或更新,最好使用 batch
find all the active contacts of a given user
根据提议的tables,如果请求者的邮箱是test@email.com:
SELECT * FROM active_connections WHERE requester_email = 'test@email.com'
update user as favourite
将批量更新connections
中的记录并将新记录添加到favourite_connections
:
BEGIN BATCH
UPDATE connections
SET is_favourite = true, last_update = dateof(now())
WHERE requester_email ='test@email.com'
AND recipient_email = 'john.smith@test.com';
INSERT INTO favourite_connections (
requester_email, recipient_email, recipient_name, last_update
) VALUES (
'test@email.com', 'john.smith@test.com', 'John Smith', dateof(now())
);
APPLY BATCH;
mark connection for soft deletion
连接的信息可以保留在connections
中并禁用所有标志,以及从active_connections
、favourite_connections
和paired_connections
中删除的记录
BEGIN BATCH
UPDATE connections
SET is_active = false, is_favourite = false,
is_paired = false, last_update = dateof(now())
WHERE requester_email ='test@email.com'
AND recipient_email = 'john.smith@test.com';
DELETE FROM active_connections
WHERE requester_email = 'test@email.com'
AND recipient_email = 'john.smith@test.com';
DELETE FROM favourite_connections
WHERE requester_email = 'test@email.com'
AND recipient_email = 'john.smith@test.com';
DELETE FROM paired_connections
WHERE requester_email = 'test@email.com'
AND recipient_email = 'john.smith@test.com';
APPLY BATCH;
我正在设计一个应用程序,该应用程序将使用户能够发送请求以相互联系,查看他们发送或接收的请求,在他们的交互过程中做笔记以供以后连接时参考,以及从他们的联系人中删除用户列出。
在 RDBMS 中,架构将是:
table 列为
的用户- uid(每个用户的唯一字符串)
table 请求列:
来自 - 用户 id
to - 用户id主键(from,to)
已创建 - 时间戳
消息 - 字符串
过期 - 时间戳
table 与列的连接:
来自 - 用户 id
至-用户id
主键(从,到)
注释-字符串
已创建 - 时间戳
已修改 - 时间戳
isFavourite - 是来自用户的最爱,值 0 或 1
isActive - 软删除,值为 0 或 1
pairedConnection - 显示 to 和 from 之间的连接是否已停用(to 用户从其联系人列表中删除了 from 用户),值 0 或 1
我预计需要的查询是:
查找用户发送的请求
查找某个用户收到的请求
查找给定用户的所有活动联系人
找到一个用户的所有收藏夹
找到所有从他们的列表中删除给定用户的用户
更新一个用户在遇到另一个与他有联系的用户时所做的笔记
将用户更新为最爱
将连接标记为软删除
我正在尝试在 Cassandra 中对此进行建模,但对为实现最高效率而选择的键感到困惑。
到目前为止,我有以下想法,欢迎更多有经验的Cassandra用户反馈:
create table users(
uid text PRIMARY KEY
);
create table requestsByFrom(
from text,
to text,
message text,
created timestamp,
expiry timestamp,
PRIMARY KEY (from,to)
create table requestsByTo(
from text,
to text,
message text,
created timestamp,
expiry timestamp,
PRIMARY KEY (to,from)
);
create table connections(
from text,
to text,
notes text,
created timestamp,
modified timestamp,
isFavourite boolean,
isActive boolean,
pairedConnection boolean,
PRIMARY KEY (from,to)
);
create table activeConnections(
from text,
to text,
isActive boolean,
PRIMARY KEY (from,isActive)
);
create table favouriteConnections(
from text,
to text,
isFavourite boolean,
PRIMARY KEY (from, isFavourite)
);
create table pairedConnection(
from text,
to text,
pairedConnection boolean,
PRIMARY KEY ((from,to), pairedConnection)
);
Cassandra 具有与 RDBMS 不同的范例,这一点在必须完成数据建模的方式上更为明显。您需要记住,首选非规范化,并且您会有重复的数据。
table的定义应该是基于查询来检索数据的,这在问题的定义中有部分说明,例如:
find the sent requests for a user
采用 table requestsByFrom
的初始设计,另一种选择是
CREATE TABLE IF NOT EXISTS requests_sent_by_user(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
message TEXT,
created TIMESTAMP
PRIMARY KEY (requester_email, recipient_email)
) WITH default_time_to_live = 864000;
注意from
是一个限制关键字,expiry
信息可以通过default_time_to_live子句(TTL)的定义来设置,它会在定义的时间后删除记录;此值为插入记录后的秒数,示例为 10 天(864,000 秒)。
主键建议是邮箱地址,也可以是UUID,名字不推荐,因为可以多人同名(如James Smith
)或同一个人名字可以有多种写法(下面的例子Jim Smith
、J. Smith
和j smith
可能指的是同一个人)
名称 recipient_name
也已添加,因为您很可能希望显示它;应添加任何其他将 displayed/used 与查询一起使用的信息。
find the received requests for a user
CREATE TABLE IF NOT EXISTS requests_received_by_user(
recipient_email TEXT,
requester_email TEXT,
requester_name TEXT,
message TEXT,
created TIMESTAMP
PRIMARY KEY (recipient_email, requester_email)
) WITH default_time_to_live = 864000;
最好使用batch同时向requests_sent_by_user
和requests_received_by_user
添加记录,这将确保两者之间信息的一致性table s,TTL(数据到期)也将相同。
storing contacts
题中有4个table连接:connections
、active_connections
、favourite_connections
、paired_connections
,两者有什么区别他们?他们会有不同的 rules/use 案例吗?如果是这样的话,将它们设置为不同的 tables:
CREATE TABLE IF NOT EXISTS connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
notes TEXT,
created TIMESTAMP,
last_update TIMESTAMP,
is_favourite BOOLEAN,
is_active BOOLEAN,
is_paired BOOLEAN,
PRIMARY KEY (requester_email, recipient_email)
);
CREATE TABLE IF NOT EXISTS active_connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
last_update TIMESTAMP,
PRIMARY KEY (requester_email, recipient_email)
);
CREATE TABLE IF NOT EXISTS favourite_connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
last_update TIMESTAMP,
PRIMARY KEY (requester_email, recipient_email)
);
CREATE TABLE IF NOT EXISTS paired_connections(
requester_email TEXT,
recipient_email TEXT,
recipient_name TEXT,
last_update TIMESTAMP,
PRIMARY KEY (requester_email, recipient_email)
);
注意去掉了boolean flag,逻辑是如果记录存在于active_connections
,会认为是活动连接
当一个新的连接被创建时,它可能在不同的tables中有几条记录;捆绑所有这些插入或更新,最好使用 batch
find all the active contacts of a given user
根据提议的tables,如果请求者的邮箱是test@email.com:
SELECT * FROM active_connections WHERE requester_email = 'test@email.com'
update user as favourite
将批量更新connections
中的记录并将新记录添加到favourite_connections
:
BEGIN BATCH
UPDATE connections
SET is_favourite = true, last_update = dateof(now())
WHERE requester_email ='test@email.com'
AND recipient_email = 'john.smith@test.com';
INSERT INTO favourite_connections (
requester_email, recipient_email, recipient_name, last_update
) VALUES (
'test@email.com', 'john.smith@test.com', 'John Smith', dateof(now())
);
APPLY BATCH;
mark connection for soft deletion
连接的信息可以保留在connections
中并禁用所有标志,以及从active_connections
、favourite_connections
和paired_connections
中删除的记录
BEGIN BATCH
UPDATE connections
SET is_active = false, is_favourite = false,
is_paired = false, last_update = dateof(now())
WHERE requester_email ='test@email.com'
AND recipient_email = 'john.smith@test.com';
DELETE FROM active_connections
WHERE requester_email = 'test@email.com'
AND recipient_email = 'john.smith@test.com';
DELETE FROM favourite_connections
WHERE requester_email = 'test@email.com'
AND recipient_email = 'john.smith@test.com';
DELETE FROM paired_connections
WHERE requester_email = 'test@email.com'
AND recipient_email = 'john.smith@test.com';
APPLY BATCH;