Hadoop HBase—如何将实体嵌套到表中的两个(+;)级别?

Hadoop HBase—如何将实体嵌套到表中的两个(+;)级别?,hadoop,hbase,bigdata,schema-design,Hadoop,Hbase,Bigdata,Schema Design,我在回顾这张[幻灯片134](Ian Varely/salesforce.com,HBase Con 2012)时,他指出,可以将实体嵌套到两个层次 下面是他给出的一个将实体嵌套一层的示例: 实体:乐队、演出;乐队1:M表演的地方 Table: Band CF:"CF" Qualifiers: "Name":<name> "Genre":<genre> "Show_<id>":venue_<id&g

我在回顾这张[幻灯片134](Ian Varely/salesforce.com,HBase Con 2012)时,他指出,可以将实体嵌套到两个层次

下面是他给出的一个将实体嵌套一层的示例:

实体:乐队、演出;乐队1:M表演的地方

Table: Band
CF:"CF"
    Qualifiers:
        "Name":<name>
        "Genre":<genre>
        "Show_<id>":venue_<id>_date_<date>_start_time_<start_time>_cover_price_<cover_price>
下面是我想到的另一个似乎更有意义的选项,即使用JSON:

"Meeting_<id>_host_<id>_start_time_<start_time>":[{attendee_id:<id>,join_time:<time>}, ..]
“会议主持人开始时间”:[{与会者id:,加入时间:},…]
但是,为什么不在meetings和columns中使用一列作为一个巨大的JSON字符串呢


这就是在HBase模式中嵌套两个级别的意思,还是有更好的方法呢?

使用简单的序列化格式(如JSON)来存储嵌套数据,而不是一些自定义的下划线分隔字符串。在您的示例中,客户1:M会议和会议1:M与会者,首先需要确定您想要的单元格粒度类型

对于单个客户,每个与会者是否都应该在自己的单元中?或者让每次会议都在自己的单元中就足够了

可以使用如下列限定符:

meeting:17          (Meeting 17)
attendee:17:5       (Meeting 17, Attendee 5)
如果你的 表存在于父子关系、主细节关系或其他严格的一对多关系中,这是 可以在HBase中将其建模为一行。行键将对应于父级 实体。嵌套的值将包含子元素,其中每个子元素都获得一个列限定符,它们的标识属性将被放入其中 存储,剩余的非标识属性存储到值中。实际HBase行定义父级 记录; 子实体的记录存储为单个列。 由于列的方式不同,您可以使用HBase的灵活性放入嵌套实体 都是设计好的。HBase不一定具有存储嵌套实体的特殊功能。 当然,这也有一些局限性。首先,这种技术只适用于一个层次:嵌套实体本身不能有嵌套实体。你仍然可以 在一个父实体中有多个不同的嵌套子实体,列限定符是它们的标识属性。 其次,访问作为嵌套列存储的单个值的效率不高 一行中的限定符,与访问另一个表中的行相比,正如您所了解的 在本章前面。 尽管如此,仍有令人信服的案例表明这种模式设计是合适的。如果 获取子实体的唯一方法是通过父实体,并且您希望对父实体的所有子实体进行事务性保护,这可能是正确的方法


From in Action

Ok,所以自定义分隔字符串可以用作列限定符名称,但我应该使用JSON/xml作为相应的值?@MatthewMoisen Yes。为列限定符使用自定义分隔字符串是有意义的,因为HBase与它们的交互非常直接。例如,使用仅与“attendee::5”匹配的限定符筛选器扫描Customer表,以查找attendee 5所在的所有会议。但从HBase的角度来看,通常单元格内容被视为一个字节[],因此使用一些非常容易处理的东西是有意义的。
"Meeting_<id>_host_<id>_start_time_<start_time>":[{attendee_id:<id>,join_time:<time>}, ..]
meeting:17          (Meeting 17)
attendee:17:5       (Meeting 17, Attendee 5)