2016-09-07 59 views
1

我是卡桑德拉的新手,想做一对多的用户及其车辆的映射。一个用户可能有多个车辆。我的用户表将包含用户的详细信息,如姓名,等。车辆表将具有车辆的详细信息。卡桑德拉一对多映射

我的选择查询将获取特定用户的所有车辆详细信息。

我应该如何在卡桑德拉设计这个?

回答

3

您可以在一个单一的表很容易对此建模关键级别。只要用户对车辆的基数不是太大(像用户拥有1000辆车一样),这应该工作得很好。

我上面考虑的情况非常简单。但是,如果我的用户有大量的20到30场的细节和车辆相同的细节会怎么样。你仍然会建议有一张表并复制所有车辆的用户数据?

这要看情况。你的用例是否需要返回所有这些?如果是这样,那么“是”我仍然会推荐这种方法。从Cassandra获得最佳查询性能的方法是模拟您的表以适合您的查询。当Cassandra可以通过特定键或一系列行(按顺序存储)读取单行时,它的工作效果最佳。您希望避免执行多个查询或编写强制Cassandra执行随机读取的查询。

有2个不同的表,如用户和车辆和车辆表会有主键为User_Id和Vehicle_Id有什么后果?

在分布式系统网络时代是敌人。通过使用两张表格,您现在可以进行两个查询......假设用户与车辆的比例为1比1。但是如果您的用户拥有8辆车,您现在需要9次查询才能实现您的结果。使用上面的设计,您可以在1个查询中构建结果集(最小化网络时间)。同样以userid作为分区键,该查询被保证由一个节点服务,而不是针对车辆数据的附加查询,这将很可能需要联系多个节点。

+1

如果我想让所有拥有特定车辆的用户该怎么办? :D – tymeJV

+0

在*的情况下,我会建立一个额外的查询表(具有相同的数据)和一个车辆类型和用户标识符的PRIMARY KEY。在Cassandra磁盘上很便宜,所以重复你的数据并不是什么大问题。 – Aaron

+0

在我看来,OP至少需要两个单独的“目录”,一个用于用户,另一个用于车辆,并且希望在这两个表之间执行典型的连接。这个答案使得不可能通过id或名字或其他来访问单个车辆。 – xmas79

1

这似乎有两个表,一个拿着所有的车辆数据,另一个用于满足您的查询一样简单:

SELECT * FROM vehicles_to_users WHERE user_id = 9; 

什么:

CREATE TABLE vehicles (
    vehicle_id bigint, 
    vehicle_type int, 
    vehicle_name text, 
    ... 
    PRIMARY KEY (vehicle_type) 
) 

CREATE TABLE vehicles_to_users (
    user_id bigint, 
    vehicle_id bigint, 
    vehicle_type int, 
    vehicle_name text, 
    ... 
    PRIMARY KEY (user_id, vehicle_type) 
) 

然后你会被查询像那样获得属于特定用户的所有特定车型:

SELECT * FROM vehicles_to_users WHERE user_id = 9 AND vehicle_type = 1; 

这是解决非规范化数据,你应该考虑的,而不是有类似的东西的方法:因为它属于关系型数据库的世界,你必须运行N + 1个查询

CREATE TABLE vehicles (
    vehicle_id bigint, 
    vehicle_type int, 
    vehicle_name text, 
    ... 
    PRIMARY KEY (vehicle_type) 
) 

CREATE TABLE vehicles_to_users (
    user_id bigint, 
    vehicle_id bigint, 
    PRIMARY KEY (user_id) 
) 

满足您的要求:一个得到所有属于特定用户的ID,然后N次查询以获得每个车辆的所有信息:

SELECT * FROM vehicles_to_users WHERE user_id = 9; 
SELECT * FROM vehicles WHERE vehicle_id = 115; 
SELECT * FROM vehicles WHERE vehicle_id = 116; 
SELECT * FROM vehicles WHERE vehicle_id = ...; 

而且不要试图使用IN clausole是这样的:

SELECT * FROM vehicles WHERE vehicle_id IN (115,116,....); 

因为它会因协调节点必须做的额外工作而更糟。这样你就可以一次性查询车辆为单个用户

CREATE TABLE userVehicles (
    userid text, 
    vehicleid text, 
    name text static, 
    surname text static, 
    vehicleMake text, 
    vehicleModel text, 
    vehicleYear text, 
    PRIMARY KEY (userid,vehicleid) 
); 

,和您的用户数据可以static,使其存储在分区:

+0

感谢您的回复。但我不明白为什么我们需要车辆表时,我们有vehicles_to_users表的地方?或者,而不是用户表,您定义上面的车辆表? – NGR

+0

对不起,可能我不太清楚。我假设你已经有'用户'表,我没有写它,因为它非常普通。我假设你已经有'车辆表'(因为您可能需要直接收集有关车辆的信息,例如通过其ID)。 'vehicles_to_users'是你的答案,因为你可以通过'user_id'查询车辆。一个查询 - >通常一个表格... – xmas79