我正在继续探索Cassandra,我想创建Student< =>课程关系类似于RDBMS上的多对多。
在查询方面,我将使用以下查询;
假设我创建了Column Families。一个用于课程,另一个用于学生。
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:studentId
CompisiteKey创建第三列系列吗?如果是,我可以使用Hector仅通过一个(左或右)复合键组件进行查询吗?
请帮忙。
更新:
根据建议,我创建了以下架构:
学生:
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'] ='';
答案 0 :(得分: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
这是我们有很多列的广泛行,名称为'fieldname','rowkey to actual course'
课程行更有趣......因为用户认为加载单个课程的学生可能会导致内存不足,他使用的光标在循环时只加载500个。
在这种情况下,PlayOrm将支持两个课程。 Sooo,让我们把我们的用户排在上面,他当然是rowkey56所以让我们来描述那个课程
rowkey56 = name='coursename', description='somedesc', lecturer='rowkey89ToLecturer'
然后,学生的某个索引表中还有另一行(这是一个非常宽的行,因此可以支持数百万学生)
indexrowForrowkey56InCourse = student34.56, student39.56, student.23.56....
into the millions of students
如果您希望课程的学生人数超过数百万,那么您需要考虑分区是否使用playOrm。如果你需要,PlayOrm会为你做分区。
注意:如果你不知道hibernate或JPA,当你加载上面的Student时,它会加载一个代理列表,所以如果你开始循环遍历这些课程,它会回到noSQL商店并加载课程,所以你不必;)。
对于Course,它会加载一个未填写的代理讲师,直到您访问讲座,如lecturer.getName()。如果你调用讲授.getId(),它不需要加载讲师,因为它已经从课程行中有了。
编辑(更多细节):PlayOrm有3个索引表Decimal(存储double,float等和BigDecimal),Integer(long,short等,BigInteger和boolean)和String索引表。当您使用CursorToMany时,它将使用其中一个表,具体取决于键的FK类型。它还将这些表用于它的Scalable-SQL语言。它在CursorToMany上使用单独行的原因只是因为客户端在读取行时没有得到OutOfMemory,因为toMany在某些情况下可能有一百万个FK。然后CursorToMany从该索引行批量读取。
后, 迪安