gpt4 book ai didi

Cassandra 用于无模式数据库,每天数百万个订单表和数百万个查询

转载 作者:行者123 更新时间:2023-12-04 12:42:18 26 4
gpt4 key购买 nike

我正在构建一个数据库,具有以下特征:

  • 每行具有可变列数的无模式数据库。
  • 数以千万计的记录和数以千万计的列。
  • 每天数百万次查询。
  • 每天写入数千条。
  • 查询将过滤几列(不仅是键)。

  • 我正在考虑按比例构建的 Cassandra。

    我的问题是:
  • 在这种情况下我需要水平缩放吗?
  • Cassandra 是否支持有多个键指向同一个列族?


  • 编辑

    我想确保我的观点是正确的。因此,以下示例记录了我从您的回答中得到的信息:

    所以,如果我们有以下列族(它包含一些商店产品及其详细信息)

    products // column-family name
    {
    x = { "id":"x", // this is unique id for the row.
    "name":"Laptop",
    "screen":"15 inch",
    "OS":"Windows"}
    y = { "id":"y", // this is unique id for the row.
    "name":"Laptop",
    "screen":"17 inch"}
    z = { "id":"z", // this is unique id for the row.
    "name":"Printer",
    "page per minute":"20 pages"}
    }

    并且,我们要添加“名称”搜索参数,我们将创建另一个具有不同行键的 CF 副本,如下所示:

    products
    {
    "x:name:Laptop" = { "id":"x",
    "name":"Laptop",
    "screen":"15 inch",
    "OS":"Windows"}
    "y:name:Laptop" = { "id":"y",
    "name":"Laptop",
    "screen":"17 inch"}
    "z:name:Printer" = { "id":"z",
    "name":"Printer",
    "ppm":"20 pages"}
    }

    同样,为了添加“屏幕”搜索参数:

    products
    {
    "x:screen:15 inch" = { "id":"x"
    "name":"Laptop",
    "screen":"15 inch",
    "OS":"Windows"}
    "y:screen:17 inch" = { "id":"y",
    "name":"Laptop",
    "screen":"17 inch"}
    }

    但是,如果我们想根据 10 个搜索参数或它们的任意组合进行查询(如我的应用程序中的情况),那么我们必须创建 1023 个列族副本 [(2 的 10 次方)- 1]。而且由于大多数行都会有很多搜索参数,这意味着我们需要大约 1000 倍的额外存储来对数据进行建模(以这种方式),这并不小,特别是如果我们在原始 CF 中有 10,000,000 行。

    这是您建议的数据模型吗?

    还有一点:我不明白为什么创建二级索引会放弃或剥夺无模式模型。

    最佳答案

    Cassandra 不是一个数据库,您可以通过除行键之外的任何其他内容进行查询。但是您可以定制数据模型以支持这些查询。

    我们每天在 6 cassandra 节点集群上执行 175,000,000 次查询(简单!)但我们只使用 row_keys 和列请求数据,因为我们已经让我们的数据模型以这种方式工作。我们不使用索引查询。

    为了支持更丰富的查询,我们使用我们将用作搜索参数的数据对我们的数据进行非规范化,以制作检索数据的键。

    示例:考虑我们保存以下对象:

    obj {
    id : xxx //assuming id is a unique id across the system
    p1 : value1
    p2 : value2
    }

    我们知道我们想通过这些参数中的任何一个进行搜索,然后我们将保存 obj 的副本
    对于 column_names 或键,如下所示:

    "p1:value1:xxx"
    "p2:value2:xxx"
    "p1:value1:p2:value2:xxx"
    "xxx"

    这样我们就可以使用 p1 = value1, p2 = value2, p1 = value1 AND p2 = value2 或仅通过它的唯一 id xxx 来搜索 obj。

    如果您不想这样做,唯一的其他选择是使用二级索引和索引查询,但这将丧失您的问题的“无模式”要求。

    编辑 - 一个例子。

    我们要保存定义为的对象“产品”
    class Products{
    string uid;
    string name;
    int screen_size; //in inches
    string os;
    string brand;
    }

    我们将其序列化为字符串或字节数组(我总是倾向于使用 Jackson Json 或 Protobuf ......两者都与 cassandra 配合得很好,而且速度非常快)。
    我们将该字节数组放入一列。

    现在重要的部分是:创建列名和行键。
    假设我们想按屏幕分辨率进行搜索,并可能按品牌进行过滤。
    我们将屏幕尺寸的桶定义为 ["0_to15", "16_to_21", "21_up"]

    给定列:

    "{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}

    一份副本保存为:
    - key = "brand:Samsung"and column_name = "screen_size:15_uid:MI615FMDO548"
    - key = "brand:0_to_15"和 column_name = "screen_size:15_uid:MI615FMDO548"

    为什么要在列名中添加 uid?
    使唯一产品的所有列名称都是唯一的。

    示例第 2 部分 现在让我们说我们已经添加了

    "{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
    "{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}"
    "{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
    "{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"

    我们最终会得到以下列族:

    Products{
    -Row:"brand:Samsung"
    => "screen_size:13_uid:MI615FMDO687":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
    => "screen_size:14_uid:MI615FMD5589":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
    => "screen_size:15_uid:MI615FMDO548":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
    => "screen_size:17_uid:MI615FMD1111":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
    -Row:"screen_size:0_to_15"
    => "brand:Samsung_uid:MI615FMDO687":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
    => "brand:Samsung_uid:MI615FMD5589":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
    => "brand:Samsung_uid:MI615FMDO548":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
    -Row:"screen_size:16_to_17"
    => "brand:Samsung_uid:MI615FMD1111":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
    -Row:"uid:MI615FMDO687"
    => "product":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
    -Row:"uid:MI615FMD5589"
    => "product":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
    -Row:"uid:MI615FMDO548"
    => "product":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
    -Row:"uid:MI615FMD1111"
    => "product":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
    }

    现在,通过跨列名称使用范围查询,您可以按品牌和屏幕尺寸进行搜索。

    希望这是有用的

    关于Cassandra 用于无模式数据库,每天数百万个订单表和数百万个查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11847064/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com