【问题标题】:How to move from MySQL to Cassandra modeling如何从 MySQL 迁移到 Cassandra 建模
【发布时间】:2015-01-29 03:14:24
【问题描述】:

我正在尝试从 MySQL 迁移到 Cassandra,以构建我正在构建的音乐服务应用程序。

我已阅读以下 stackexchange:MySQL Data Model to Cassandra Help?

并检查了https://wiki.apache.org/cassandra/DataModel - 还有他们对音乐服务所做的 DataStax Cassandra 建模,但到目前为止的文档非常小而且很窄,我无法放弃 MySql 类型查询,所以我需要帮助.

这是我目前在 mysql 中工作的专辑表

CREATE TABLE `albums` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(150) NOT NULL,
  `description` varchar(300) NOT NULL,
  `release_date` int(10) unsigned NOT NULL,
  `status` enum('active','inactive','pending') NOT NULL,
  `licensor_id` int(11) NOT NULL,
  `score` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `status` (`status`),
  KEY `licensor_id` (`licensor_id`),
  KEY `batch_id` (`batch_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1720100 ;

我在下表中也有一对多的关系:艺术家(一张专辑有很多艺术家)、流派(一张专辑有很多流派)、歌曲(一张专辑包含很多歌曲)。

为了将它们耦合起来,我有很多数据透视表。

所以因为 Cassandra 不允许连接,所以我认为执行 set,list,map 可以帮助我解析到正确的数据集。

起初我的想法是通过重复使用同一张表来解决我的映射问题:

CREATE TABLE `albums` (
  `id` int(10) ,
  `title` varchar(150) ,
  `description` varchar(300) ,
  `release_date` date ,
  `status` enum('active','inactive','pending') ,
  `licensor_id` int(11) ,
  `data_source_provider_id` int(10) ,
  `score` int(10)
  `genre` <set>
  `artist` <set>
  PRIMARY KEY (`id`),
) ;

(抱歉,如果上面的语法不是 Cassandra 的正确语法,我才开始在开发系统上安装系统)

我的查询如下:

  1. 给我所有按分数(降序)排序的专辑
  2. 给我一个特定流派的所有专辑,按分数排序
  3. 给我某个特定艺术家的所有专辑,按分数排序
  4. 给我所有按发行日期排序的专辑,然后按分数。

在 SQL 中,执行连接时 4 很容易 - 但是由于 Cassandra 不允许连接,我认为我的建模足够充分,但是无法满足 #4(据我所知,没有双重顺序) .

多个索引很慢,并且考虑到它在一个大型数据集上(目前有 180 万条记录,但我计划至少抽取三倍的数量,因此为什么 Cassandra 会很有用)

我的问题是:

1) 我从 MySQL 到 Cassandra 的路径是否正确,尽管我被困在 4 个问题上 - 还是它做错了? (我之前用 MongoDB 做过一些活动记录,您可以在文档中拥有一个子实体,但 Cassandra 只有 set、list 和 map)。

2) 如果我想将我的建模扩展为:“我想创建一个列表 X,其中包含来自专辑表的预定义数字元素”。将使用具有 X 的新字段“标签”标记每个专辑元素是过滤事物的明智方法,或者最好创建一个新表,其中包含我需要的所有元素并进行查询。

【问题讨论】:

    标签: mysql database cassandra


    【解决方案1】:

    Cassandra 的一般建议是根据您的查询编写表。如果其中一些查询彼此不兼容,请不要羞于将相同的数据写入多个表。 (例如,Twitter 会将每条推文写入该用户所有关注者的表中。)

    也就是说,看看您的查询,您面临的挑战将是 Cassandra 本身并没有办法处理您的某些排序需求。您将需要添加像 Spark 或 Hadoop 的 M/R 这样的分析引擎来对分数等非唯一(不断变化?)字段进行排序。

    让我们看一些表定义,这将是一个好的开始。然后,您可以确定是否需要一个成熟的分布式分析引擎,或者本地排序查询结果是否就足够了。

    CREATE TABLE albums(
      id uuid,
      title text,
      description text,
      releasedate timestamp,
      status text,
      license_id varint,
      data_source_provider_id varint,
      score counter,
      genre set<text>,
      artist set<text>,
      PRIMARY KEY (id)
    );
    

    此表将按 id 存储您的所有专辑。根据您的用例,选择所有专辑并按分数对其进行排序肯定是不可能的。你可以,潜在地,做一些聪明的事情,比如对分数进行模数并将专辑放入桶中,但我不相信这会扩展。您的任何查询都可以使用此表和分析来回答,但为了完整起见,让我们看看将您的数据放入 Cassandra 的其他一些选项。以下每个表格都可以轻松减少您运行的任何具有附加参数(如日期范围或类型集)的分析调查的负载。

    CREATE TABLE albums(
      id uuid,
      title text,
      description text,
      releasedate timestamp,
      status text,
      license_id varint,
      data_source_provider_id varint,
      score counter,
      genre set<text>,
      artist text,
      PRIMARY KEY (artist, releasedate, title)
    ); 
    

    Cassandra 可以自动对不可变字段进行排序。上表会将每个艺术家的专辑存储在一个单独的分区中(每个分区都位于您的集群中并根据您的复制因子进行复制)。如果一张专辑有多个艺术家,则该记录将在每个艺术家的条目下复制,这没关系。第二个和第三个键(发布日期和标题)被认为是排序键。 Cassandra 将首先按发布日期对专辑进行排序,然后按标题对专辑进行排序(对于其他优先级,请颠倒它们的上述顺序)。艺术家、发布日期和标题的每个组合在逻辑上都是一行(尽管在磁盘上,它们将仅存储为每个艺术家的宽行)。对于一位艺术家,您可能可以在本地按分数对条目进行排序,而无需数据库的直接干预。

    可以通过类似的表格轻松完成按发布日期排序,但将 PRIMARY KEY 更改为:PRIMARY KEY (releasedate, ..?)。但是,在这种情况下,如果您有大量发布日期,您可能会在(本地)排序方面面临挑战。

    最后,不要为流派尝试类似的东西。流派太大,无法包含在单个分区键中。假设您有第二种拆分设置的方法,您可以执行 PRIMARY KEY ((genre,artist)), (double parens intental) 但我认为这与您的特定用例不太适合,因为这两个键需要查找条目。

    【讨论】:

    • 至于(可能)选择一个分析引擎来混合,你的两个主要选择是 DataStax Enterprise,一个围绕 Cassandra 构建的商业产品(对初创公司免费)和 Apache Spark(顺便说一下,这包含在DataStax 产品),它有一个连接器,因此它可以使用 Cassandra 作为其分布式数据存储。
    猜你喜欢
    • 1970-01-01
    • 2017-08-19
    • 2020-11-18
    • 2017-01-07
    • 1970-01-01
    • 2018-07-25
    • 2017-05-09
    • 2013-11-28
    • 2011-08-31
    相关资源
    最近更新 更多