Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
熟悉SQL的人迁移到Cassandra/NoSQL的概述_Cassandra_Nosql - Fatal编程技术网

熟悉SQL的人迁移到Cassandra/NoSQL的概述

熟悉SQL的人迁移到Cassandra/NoSQL的概述,cassandra,nosql,Cassandra,Nosql,在处理关系数据库多年之后,我很乐意接受规范化的洗脑,转而考虑表、列和行。卡桑德拉仍在我的脑海中闪过,完全被它包围着 我更了解持久化映射,您只能查询这些映射的唯一键,但我的理解是不完整的 是的,我是RTFM。不过,有人能给我一个很好的,简洁的描述卡桑德拉如何结构数据与SQL数据库?我是说,1000英尺的视野,它是如何工作的 例如,在易趣科技博客上,它说: 不要考虑关系表 相反,请考虑嵌套、排序的地图数据结构。 资料来源: 我几乎完全明白了。。。但不完全如此 这些都是很好的答案。添加了一个悬赏,以

在处理关系数据库多年之后,我很乐意接受规范化的洗脑,转而考虑表、列和行。卡桑德拉仍在我的脑海中闪过,完全被它包围着

我更了解持久化映射,您只能查询这些映射的唯一键,但我的理解是不完整的

是的,我是RTFM。不过,有人能给我一个很好的,简洁的描述卡桑德拉如何结构数据与SQL数据库?我是说,1000英尺的视野,它是如何工作的

例如,在易趣科技博客上,它说:

不要考虑关系表

相反,请考虑嵌套、排序的地图数据结构。 资料来源:

我几乎完全明白了。。。但不完全如此



这些都是很好的答案。添加了一个悬赏,以查看它是否会激励任何人做出更权威的响应。

使用关系数据库定义列,并且每行都有这些列(过于简化)

对于Cassandra(以及HBase),每一行都有自己的列,这些列表示为名称/值对。每行也有一个行键


您可以决定每一行将具有相同的列名(称为“静态模型”),这将模拟数据在关系数据库中的存储方式。或者您可以有一个动态的或“宽行”模型,其中列名在每行之间不一定相同。在后一种模型中,列名可以是时间戳,例如,对应的值是tweet、事务或天气指标。您可以随意实现所需的任何其他结构,只要每行保留一个行键和列名/值对。

注意:由于最初的问题是关于Cassandra的,因此这将是本答案的重点。虽然Cassandra和其他非关系(NoSQL)数据存储通常共享类似的概念,但不能假设这里详细介绍的思想将适用于其他非关系数据存储

实现这一点的最佳方法是记住,构建数据模型以适应查询是标准实践(对于Cassandra而言)。主要区别在于,RDBMS表是以高效的数据存储为主要焦点构建的。在Cassandra(非关系型)世界中,主要关注点变为您希望查询的外观。通常,这可能转化为以多种方式存储相同的冗余数据……这没关系。这在数据税务文件中有解释

假设我有以下用户表:

CREATE TABLE users (
    username TEXT,
    firstname TEXT,
    lastname TEXT,
    phone TEXT,
    PRIMARY KEY (username));
插入一些示例数据后,该表如下所示:

username  | firstname | lastname | phone
------------------------------------------------
mreynolds | Malcolm   | Reynolds | 111-555-1234
jcobb     | Jayne     | Cobb     | 111-555-3464
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
PRIMARY KEY (phone,username));
SELECT username, firstname, lastnamea, phone FROM usersbyphone;

username  | firstname | lastname | phone
------------------------------------------------
hwashburne| Hoban     | Washburne| 111-555-1212
jcobb     | Jayne     | Cobb     | 111-555-3464
mreynolds | Malcolm   | Reynolds | 111-555-1234
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
zwashburne| Zoe       | Washburne| 111-555-1212
RowKey:mreynolds
=> (column=, value=, timestamp=1374546754299000)
=> (column=firstname, value=Malcolm, timestamp=1374546754299000)
=> (column=lastname, value=Reynolds, timestamp=1374546754299000)
=> (column=phone, value=111-555-1234, timestamp=1374546754299000)
------------------------------------------------------
RowKey:hwashburne
=> (column=, value=, timestamp=1374546757815000)
=> (column=firstname, value=Hoban, timestamp=1374546757815000)
=> (column=lastname, value=Washburne, timestamp=1374546757815000)
=> (column=phone, value=111-555-1212, timestamp=1374546757815000)
------------------------------------------------------
RowKey:zwashburne
=> (column=, value=, timestamp=1374546761055000)
=> (column=firstname, value=Zoe, timestamp=1374546761055000)
=> (column=lastname, value=Washburne, timestamp=1374546761055000)
=> (column=phone, value=111-555-1212, timestamp=1374546761055000)
users
表允许我通过
username
查询我的用户,因为这是我们的主键。但如果我们想通过电话号码查询数据呢?您可能想在
手机
上添加二级索引,但
手机
的基数可能与
用户名
一样高。解决这个问题的正确方法是创建一个新表,允许您通过电话进行查询。注意:此模型假设
用户名
电话
都是唯一的

CREATE TABLE usersbyphone (
    phone TEXT,
    username TEXT,
    firstname TEXT,
    lastname TEXT,
    PRIMARY KEY (phone));
假设我们的下一个条目是针对用户“Hoban Washburne”和“Zoe Washburne”的。当他们结婚后,他们将拥有相同的(家庭)电话号码。Cassandra将不允许条目共享主键,并将覆盖(最后一个条目获胜)。因此,我们需要更改
usersbyphone
表上的主键,如下所示:

username  | firstname | lastname | phone
------------------------------------------------
mreynolds | Malcolm   | Reynolds | 111-555-1234
jcobb     | Jayne     | Cobb     | 111-555-3464
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
PRIMARY KEY (phone,username));
SELECT username, firstname, lastnamea, phone FROM usersbyphone;

username  | firstname | lastname | phone
------------------------------------------------
hwashburne| Hoban     | Washburne| 111-555-1212
jcobb     | Jayne     | Cobb     | 111-555-3464
mreynolds | Malcolm   | Reynolds | 111-555-1234
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
zwashburne| Zoe       | Washburne| 111-555-1212
RowKey:mreynolds
=> (column=, value=, timestamp=1374546754299000)
=> (column=firstname, value=Malcolm, timestamp=1374546754299000)
=> (column=lastname, value=Reynolds, timestamp=1374546754299000)
=> (column=phone, value=111-555-1234, timestamp=1374546754299000)
------------------------------------------------------
RowKey:hwashburne
=> (column=, value=, timestamp=1374546757815000)
=> (column=firstname, value=Hoban, timestamp=1374546757815000)
=> (column=lastname, value=Washburne, timestamp=1374546757815000)
=> (column=phone, value=111-555-1212, timestamp=1374546757815000)
------------------------------------------------------
RowKey:zwashburne
=> (column=, value=, timestamp=1374546761055000)
=> (column=firstname, value=Zoe, timestamp=1374546761055000)
=> (column=lastname, value=Washburne, timestamp=1374546761055000)
=> (column=phone, value=111-555-1212, timestamp=1374546761055000)
这里,
phone
是我们的分区键(决定存储此行的分区的键),而
username
是我们的集群键(决定磁盘排序顺序的键)。在复合主键中同时使用这两个将确保唯一性。这将允许我们像这样选择
usersbyphone
表:

username  | firstname | lastname | phone
------------------------------------------------
mreynolds | Malcolm   | Reynolds | 111-555-1234
jcobb     | Jayne     | Cobb     | 111-555-3464
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
PRIMARY KEY (phone,username));
SELECT username, firstname, lastnamea, phone FROM usersbyphone;

username  | firstname | lastname | phone
------------------------------------------------
hwashburne| Hoban     | Washburne| 111-555-1212
jcobb     | Jayne     | Cobb     | 111-555-3464
mreynolds | Malcolm   | Reynolds | 111-555-1234
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
zwashburne| Zoe       | Washburne| 111-555-1212
RowKey:mreynolds
=> (column=, value=, timestamp=1374546754299000)
=> (column=firstname, value=Malcolm, timestamp=1374546754299000)
=> (column=lastname, value=Reynolds, timestamp=1374546754299000)
=> (column=phone, value=111-555-1234, timestamp=1374546754299000)
------------------------------------------------------
RowKey:hwashburne
=> (column=, value=, timestamp=1374546757815000)
=> (column=firstname, value=Hoban, timestamp=1374546757815000)
=> (column=lastname, value=Washburne, timestamp=1374546757815000)
=> (column=phone, value=111-555-1212, timestamp=1374546757815000)
------------------------------------------------------
RowKey:zwashburne
=> (column=, value=, timestamp=1374546761055000)
=> (column=firstname, value=Zoe, timestamp=1374546761055000)
=> (column=lastname, value=Washburne, timestamp=1374546761055000)
=> (column=phone, value=111-555-1212, timestamp=1374546761055000)
需要注意的是,
usersbyphone
表并不取代
users
表……它与之协同工作。您将有一些关于该数据集的查询需要由
users
表提供,还有一些查询需要由
usersbyphone
表提供。缺点是保持两个表同步是在数据库之外完成的,通常是由应用程序代码完成的。这是一个例子,说明了在非关系范式中,您的思维必须有所不同

正如DataStax MVP John Berryman()所解释的那样,在引擎盖下,Casssandra将把我们的
用户
数据存储在如下结构中:

username  | firstname | lastname | phone
------------------------------------------------
mreynolds | Malcolm   | Reynolds | 111-555-1234
jcobb     | Jayne     | Cobb     | 111-555-3464
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
PRIMARY KEY (phone,username));
SELECT username, firstname, lastnamea, phone FROM usersbyphone;

username  | firstname | lastname | phone
------------------------------------------------
hwashburne| Hoban     | Washburne| 111-555-1212
jcobb     | Jayne     | Cobb     | 111-555-3464
mreynolds | Malcolm   | Reynolds | 111-555-1234
sbook     | Derial    | Book     | 111-555-2349
stam      | Simon     | Tam      | 111-555-8899
zwashburne| Zoe       | Washburne| 111-555-1212
RowKey:mreynolds
=> (column=, value=, timestamp=1374546754299000)
=> (column=firstname, value=Malcolm, timestamp=1374546754299000)
=> (column=lastname, value=Reynolds, timestamp=1374546754299000)
=> (column=phone, value=111-555-1234, timestamp=1374546754299000)
------------------------------------------------------
RowKey:hwashburne
=> (column=, value=, timestamp=1374546757815000)
=> (column=firstname, value=Hoban, timestamp=1374546757815000)
=> (column=lastname, value=Washburne, timestamp=1374546757815000)
=> (column=phone, value=111-555-1212, timestamp=1374546757815000)
------------------------------------------------------
RowKey:zwashburne
=> (column=, value=, timestamp=1374546761055000)
=> (column=firstname, value=Zoe, timestamp=1374546761055000)
=> (column=lastname, value=Washburne, timestamp=1374546761055000)
=> (column=phone, value=111-555-1212, timestamp=1374546761055000)
地图的概念(在易趣的文章中提到)肯定会在这里发挥作用。我们的
usersbyphone
表与
users
表看起来有些不同:

RowKey:111-555-1234
=> (column=mreynolds, value=, timestamp=1374546754299000)
=> (column=mreynolds:firstname, value=Malcolm, timestamp=1374546754299000)
=> (column=mreynolds:lastname, value=Reynolds, timestamp=1374546754299000)
------------------------------------------------------
RowKey:111-555-1212
=> (column=hwashburne, value=, timestamp=1374546757815000)
=> (column=hwashburne:firstname, value=Hoban, timestamp=1374546757815000)
=> (column=hwashburne:lastname, value=Washburne, timestamp=1374546757815000)
=> (column=zwashburne, value=, timestamp=1374546761055000)
=> (column=zwashburne:firstname, value=Zoe, timestamp=1374546761055000)
=> (column=zwashburne:lastname, value=Washburne, timestamp=1374546761055000)
由于主键结构,请注意Wash(hwashburne)和Zoe(zwashburne)在技术上是如何存储在同一行中的。此结构允许我们快速查询共享同一电话号码的所有用户

总之:

  • 要以最有效的方式使用表(列族)来查询数据。RDBMS鼓励使用规范化来最有效地存储数据
  • 使用复合键,Cassandra将相似的数据分组到附近的行中
  • Cassandra利用磁盘(群集)排序顺序优化操作
  • Cassandra主键总是唯一的。对具有相同主键的数据的不同写入将相互覆盖(最后一次写入获胜)
  • CQL(Cassandra查询语言)是SQL的有限子集。虽然CQL提供了那些来自RDBMS背景、具有熟悉语法的人,但重要的是要记住,CQL中没有许多SQL关键字和概念

    • 有很多不同之处。我会尽力帮忙的:

      • sqldbs主要依赖于B-tree数据结构。因此,您定义了一个数据模式,每个模式包含列、大小和RDBMS