1

私はCassandraの調査を続けており、RDBMSの多対多に似たStudent<=>コース関係を作成したいと思います。

クエリに関しては、次のクエリを使用します。

  1. 学生が登録したすべてのコースを取得します。
  2. 特定のコースに登録されているすべての学生を取得します。

列ファミリーに作成するとします。1つはコース用、もう1つは学生用です。

CREATE COLUMN FAMILY student with comparator = UTF8Type AND key_validation_class=UTF8Type and column_metadata=[ 
{column_name:firstname,validation_class:UTF8Type} 
{column_name:lastname,validation_class:UTF8Type}
{column_name:gender,validation_class:UTF8Type}];


CREATE COLUMN FAMILY course with comparator = UTF8Type AND key_validation_class=UTF8Type and column_metadata=[ 
{column_name:name,validation_class:UTF8Type} 
{column_name:description,validation_class:UTF8Type}
{column_name:lecturer,validation_class:UTF8Type}
{column_name:assistant,validation_class:UTF8Type}];

では、どのように進めればよいですか?

courseID:studentIdCompisiteKeyを使用して3番目の列ファミリーを作成する必要がありますか?はいの場合、Hectorを使用して1つ(左または右)の複合キーコンポーネントのみでクエリを実行できますか?

助けてください。

アップデート:

提案に従って、次のスキーマを作成しました。

学生の場合:

CREATE COLUMN FAMILY student with comparator = UTF8Type and key_validation_class=UTF8Type and default_validation_class=UTF8Type;

次に、いくつかのデータを追加します。

set student['student.1']['firstName']='Danny'
set student['student.1']['lastName']='Lesnik'
set student['student.1']['course.1']=''
set student['student.1']['course.2']='';

コースの列ファミリを作成します。

CREATE COLUMN FAMILY course with comparator = UTF8Type and key_validation_class=UTF8Type and default_validation_class=UTF8Type;

いくつかのデータを追加します。

set course['course.1']['name'] ='History'
set course['course.1']['description'] ='History Course'
set course['course.1']['name'] ='Algebra'
set course['course.1']['description'] ='Algebra Course'

そして最後にコースの学生:

CREATE COLUMN FAMILY StudentInCourse with comparator = UTF8Type and key_validation_class=UTF8Type and default_validation_class=UTF8Type;

データの追加:

set StudentInCourse['studentIncourse.1']['student.1'] =''; 
set StudentInCourse['studentIncourse.2']['student.1'] =''; 
4

1 に答える 1

1

以下でデータモデルを定義しましたが、最初にオブジェクトモデルを記述してから行モデルに飛び込む方が簡単なので、PlayOrmの観点からは次のようになります。

public class Student {
  @NoSqlId
  private String id;
  private String firstName;
  private String lastName;
  @ManyToMany
  private List<Course> courses = new ArrayList(); //constructing avoids nullpointers
}

public class Course {
  @NoSqlId
  private String id;
  private String name;
  private String description
  @ManyToOne
  private Lecturer lecturer;
  @ManyToMany
  private CursorToMany students = new CursorToManyImpl();
}

コースでListを使用することもできましたが、何年にもわたって何年にもわたってコースを受講する学生が多すぎると、OutOfMemoryが発生する可能性があるのではないかと心配していました。それでは、PlayOrmの機能にジャンプしてみましょう。必要に応じて、同様のことができます。

単一の学生の行は次のようになります

rowKey(the id in above entity) = firstName='dean',
lastName='hiller' courses.rowkey56=null, courses.78=null, courses.98=null, courses.101=null

これは、「フィールド名」および「実際のコースへの行キー」という名前の列が多数ある幅の広い行です。

コースの行はもう少し興味深いです....ユーザーは、単一のコースにすべての学生をロードするとメモリが不足する可能性があると考えているため、ループするときに一度に500しかロードしないカーソルを使用します。

この場合、PlayOrmが持つコースを裏付ける2つの行があります。すっごく、上のユーザー行を見てみましょう。彼はコースrowkey56にいたので、そのコースについて説明しましょう。

rowkey56 = name='coursename', description='somedesc', lecturer='rowkey89ToLecturer'

次に、学生用のインデックステーブルに別の行があります(これは非常に幅の広い行なので、最大数百万人の学生をサポートします)

indexrowForrowkey56InCourse = student34.56, student39.56, student.23.56.... 
into the millions of students

ただし、コースに数百万人を超える学生を含める場合は、playOrmを使用するかどうかに関係なくパーティション分割を検討する必要があります。PlayOrmは、必要に応じてパーティショニングを行います。

注:休止状態またはJPAがわからない場合は、上記のStudentをロードするとプロキシリストが読み込まれるため、コースのループを開始すると、noSQLストアに戻ってコースが読み込まれるため、した方が良い ;)。

Courseの場合、leacter.getName()のようなプロパティフィールドにアクセスするまで入力されないプロキシLecturerをロードします。Lecturer.getId()を呼び出す場合、Course行から既に講師をロードしているため、講師をロードする必要はありません。

編集(詳細):PlayOrmには、Decimal(double、floatなどとBigDecimalを格納)、Integer(long、shortなどとBigIntegerとboolean)、およびStringインデックステーブルの3つのインデックステーブルがあります。CursorToManyを使用すると、FKタイプのキーに応じて、これらのテーブルの1つが使用されます。また、Scalable-SQL言語用にこれらのテーブルを使用します。CursorToManyで別の行を使用する理由は、toManyに100万のFKが含まれている可能性があるため、クライアントが行の読み込み時にOutOfMemoryを取得しないようにするためです。次に、CursorToManyは、そのインデックス行からバッチで読み取ります。

後で、ディーン

于 2012-09-26T14:23:02.397 に答える