2016-09-07 12 views
1

私はCassandraを初めて使用しており、ユーザーとその車両の1対多のマッピングを行いたいと考えています。 1人のユーザが複数の車両を持つことがあります。私のユーザーテーブルには、氏名、姓などのユーザーの詳細が含まれます。また、車両テーブルには車両の詳細が含まれます。Cassandraの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) 
) 

は、その後、あなたがしてクエリになります。

答えて

3

あなたは簡単に単一のテーブルでこれをモデル化することができます。

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台の車のように)、これはうまく動作するはずです。

私は上記の考え方は非常に単純です。しかし、私のユーザが20〜30フィールド前後の細部を多く持ち、Vehicleについても同じである場合はどうでしょうか?それでも、あなたは単一のテーブルを持ち、すべての車両のユーザーデータをコピーすることを提案しますか?

によって異なります。あなたのユースケースでそれらのすべてを返す必要がありますか?もしそうなら、私はまだこのアプローチをお勧めします。 Cassandraから最良のクエリパフォーマンスを得る方法は、クエリに合わせてテーブルをモデル化することです。 Cassandraは、特定のキーまたは行の範囲(連続して格納されている)によって単一の行を読み取ることができるときに最適です。複数のクエリを実行したり、Cassandraにランダムな読み込みを実行させるクエリを書くことを避けたいとします。

UserとVehicleのような2つの異なるテーブルを持つと、Vehicleテーブルの主キーはUser_IdとVehicle_Idになります。

分散型ネットワークでは、時間は敵です。 2つのテーブルを持つことで、2つのクエリを作成しています。しかし、ユーザーが8台の車両を所有している場合は、結果を得るために9つのクエリが必要になります。上記の設計では、1つのクエリで結果セットを構築できます(ネットワーク時間を最小限に抑える)。また、useridをパーティションキーとして使用すると、複数のノードに接触する可能性が最も高い車両データの追加クエリとは異なり、そのクエリは1つのノードによって処理されることが保証されます。

+1

特定の車両を持つすべてのユーザーを取得する場合はどうすればよいですか? :D – tymeJV

+0

* *その場合、(同じデータを持つ)追加のクエリテーブルと、車両タイプとユーザーIDのプライマリキーを作成します。カッサンドラのディスクは安いので、あなたのデータを盗むのは大したことではありません。 – Aaron

+0

OPは、少なくとも2つの別々の「カタログ」をユーザーに1つ、車両に1つ、そして2つのテーブル間で典型的な結合を実行したいと思うようです。この答えは、IDや名前などによって単一の車両にアクセスすることは不可能になります。 – xmas79

1

この2つのテーブル、クエリを満たすためにあなたの車のすべてのデータと別のものを保持する1つを有するような単純なようです特定のユーザーに属するすべての特定の車種を取得するようなものです:

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) 
) 

:これはを持つソリューションがデータを非正規化、そしてあなたがいつも代わりのようなものを持つのアプローチを検討すべきです各車両のためのすべての情報を取得するためのクエリN、その後1は、特定のユーザーに属するすべてのIDを取得するために、そして:あなたの要件を満たす

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,....); 

コーディネータノードが余計な作業をしなければならないため、さらに悪化するためです。

+0

ご返信ありがとうございます。しかし、私は車両テーブルが必要な理由を理解していません。または、Userテーブルの代わりに上記のVehicleテーブルを定義しますか? – NGR

+0

申し訳ありませんが、おそらく私はあまり明確ではありませんでした。私はあなたが既に 'users'テーブルを持っていると思います。かなり普通ですので書きませんでした。私はあなたも既に' vehicles'テーブルを持っていると仮定しています車両の情報をIDなどで直接収集する必要があるかもしれません。 'vehicles_to_users'はあなたの答えです。なぜならあなたは' user_id'で車両を問い合わせることができるからです。 1つのクエリ - > 1つのテーブル... – xmas79

関連する問題