Cassandra 中的一对多映射
One to many mapping in Cassandra
我是 Cassandra 的新手,想对用户及其车辆进行一对多映射。一个用户可能有多个车辆。我的用户 table 将包含姓名等用户详细信息。车辆 table 将包含车辆详细信息。
我的 select 查询将获取特定用户的所有车辆详细信息。
我应该如何在 Cassandra 中设计它?
这看起来就像有两个表一样简单,一个包含您所有的车辆数据,另一个用于满足您的查询:
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;
或类似的东西来获取属于特定用户的所有特定车辆类型:
SELECT * FROM vehicles_to_users WHERE user_id = 9 AND vehicle_type = 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)
)
因为它属于关系数据库领域,你必须运行 N+1 次查询才能满足你的要求:一次获取属于特定用户的所有 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
子句:
SELECT * FROM vehicles WHERE vehicle_id IN (115,116,....);
因为协调器节点必须做额外的工作,它的性能会更差。
您可以轻松地在单个模型中对此进行建模 table:
CREATE TABLE userVehicles (
userid text,
vehicleid text,
name text static,
surname text static,
vehicleMake text,
vehicleModel text,
vehicleYear text,
PRIMARY KEY (userid,vehicleid)
);
通过这种方式,您可以一次性查询单个用户的车辆,并且您的用户数据可以 static
以便存储在分区键级别。只要用户与车辆的基数不是太大(例如,用户拥有 1000 辆车),这应该就可以正常工作。
The case I have considered above is very simple. But what if my User has lot of details around 20 to 30 fields and same for Vehicle. Still you would suggest to have a single table and copying User data for all vehicle?
视情况而定。您的用例是否需要返回所有这些?如果是这样,那么 "yes" 我仍然会推荐这种方法。从 Cassandra 获得最佳查询性能的方法是为您的 table 建模以适合您的查询。当 Cassandra 可以通过特定键或一系列行(按顺序存储)读取单行时,它的效果最好。您希望避免执行多个查询或编写强制 Cassandra 执行随机读取的查询。
What are the consequences of having 2 different tables like User and Vehicle and Vehicle table will have primary key as User_Id and Vehicle_Id?
在分布式系统网络中,时间就是敌人。通过有两个 table,您现在正在进行两个查询...假设用户与车辆的比例为 1 比 1。但是如果您的用户有 8 辆车,您现在需要 9 次查询才能获得结果。使用上面的设计,您可以在 1 个查询中构建结果集(最小化网络时间)。同样使用 userid
作为分区键,该查询保证由一个节点提供服务,而不是对车辆数据的额外查询,后者很可能需要联系多个节点。
我是 Cassandra 的新手,想对用户及其车辆进行一对多映射。一个用户可能有多个车辆。我的用户 table 将包含姓名等用户详细信息。车辆 table 将包含车辆详细信息。
我的 select 查询将获取特定用户的所有车辆详细信息。
我应该如何在 Cassandra 中设计它?
这看起来就像有两个表一样简单,一个包含您所有的车辆数据,另一个用于满足您的查询:
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;
或类似的东西来获取属于特定用户的所有特定车辆类型:
SELECT * FROM vehicles_to_users WHERE user_id = 9 AND vehicle_type = 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)
)
因为它属于关系数据库领域,你必须运行 N+1 次查询才能满足你的要求:一次获取属于特定用户的所有 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
子句:
SELECT * FROM vehicles WHERE vehicle_id IN (115,116,....);
因为协调器节点必须做额外的工作,它的性能会更差。
您可以轻松地在单个模型中对此进行建模 table:
CREATE TABLE userVehicles (
userid text,
vehicleid text,
name text static,
surname text static,
vehicleMake text,
vehicleModel text,
vehicleYear text,
PRIMARY KEY (userid,vehicleid)
);
通过这种方式,您可以一次性查询单个用户的车辆,并且您的用户数据可以 static
以便存储在分区键级别。只要用户与车辆的基数不是太大(例如,用户拥有 1000 辆车),这应该就可以正常工作。
The case I have considered above is very simple. But what if my User has lot of details around 20 to 30 fields and same for Vehicle. Still you would suggest to have a single table and copying User data for all vehicle?
视情况而定。您的用例是否需要返回所有这些?如果是这样,那么 "yes" 我仍然会推荐这种方法。从 Cassandra 获得最佳查询性能的方法是为您的 table 建模以适合您的查询。当 Cassandra 可以通过特定键或一系列行(按顺序存储)读取单行时,它的效果最好。您希望避免执行多个查询或编写强制 Cassandra 执行随机读取的查询。
What are the consequences of having 2 different tables like User and Vehicle and Vehicle table will have primary key as User_Id and Vehicle_Id?
在分布式系统网络中,时间就是敌人。通过有两个 table,您现在正在进行两个查询...假设用户与车辆的比例为 1 比 1。但是如果您的用户有 8 辆车,您现在需要 9 次查询才能获得结果。使用上面的设计,您可以在 1 个查询中构建结果集(最小化网络时间)。同样使用 userid
作为分区键,该查询保证由一个节点提供服务,而不是对车辆数据的额外查询,后者很可能需要联系多个节点。