我在 HBase 上看到了视频教程,其中数据存储在如下表中:
EmployeeName - Height - ProjectInfo
------------------------------------
Jdoe - 5'7" - ProjA-TeamLead, ProjB-Contributor
当出现一些业务需求时,需要将 ProjA 的名称更改为 ProjX 会发生什么?不会有一个单独的表来存储项目信息吗?
在关系数据库中,是的:您将有一个项目表,而员工表将通过外键引用它,并且只存储不可变的项目 ID(而不是名称)。然后,当您想查询它(在关系数据库中)时,您将执行如下 JOIN 操作:
SELECT
employee.name,
employee.height,
project.name,
employee_project_role.role_name
FROM
employee
INNER JOIN employee_project_role
ON employee_project_role.employee_id = employee.employee_id
INNER JOIN project
ON employee_project_role.project_id = project.project_id
这不是 HBase(和其他 NoSQL 数据库)的工作方式;原因是,由于这些数据库面向非常大的数据集,并且分布在许多机器上,透明地执行像这样的复杂连接的实际算法变得更加难以以性能良好的方式实现。因此,HBase 甚至没有内置连接。
相反,此类系统的一般方法是将数据非规范化,并将内容存储在单个表中。所以在这种情况下,每个员工可能有一行,并且非规范化到该行的是员工的所有项目角色信息(可能在单独的列中 - HBase 中一行的内容实际上是一个键/值映射,所以你可以轻松地表示重复的事物,例如所有不同的角色)。
不过,您是绝对正确的:如果您更改项目名称,则意味着您需要更改为每位员工存储的数据。在这方面,关系模型更“干净”。但是,如果您要处理 PB 级的数据或数万亿行,那么关系数据库的“干净”抽象就会变得更加混乱,因为您最终不得不手动将其全部分片。像 HBase 这样的系统的重点是在设计过程中预先支付这些成本,而不仅仅是假设关系数据库会神奇地为您大规模解决此类问题。(因为它不会)。
就是说:如果您不希望拥有至少 Terabtyes 的数据(记住,那是一百万 MB),只需在关系数据库中进行。会容易很多。
我认为通过这个演示文稿会给你一些观点:
http://ianvarley.com/coding/HBaseSchema_HBaseCon2012.pdf
对于更程序化的表示,请查看:
http://jimbojw.com/wiki/index.php?title=Understanding_Hbase_and_BigTable