Cassandra 非规范化与规范化

Cassandra denormalization vs normalization

非规范化现实

在我的数据库中,我有以下非规范化 table,它非常适合我的用例,而且我接收数据的速度非常快...

CREATE TABLE IF NOT EXISTS lp_webmap.link (
    drank int,
    prank int,
    title text,
    nofollow boolean,
    created timestamp,
    updated timestamp,  
    dst_ssl boolean,
    dst_www boolean,
    src_ssl boolean,
    src_www boolean,
    dst_domain_name1st text,
    dst_domain_name2nd text,
    dst_domain_name3rd text,
    src_domain_name1st text,
    src_domain_name2nd text,
    src_domain_name3rd text,
    dst_page text,
    src_page text,
    dst_page_title text,
    src_page_title text,
    src_domain_ownerreg text,
    PRIMARY KEY (
        (
            dst_domain_name1st, 
            dst_domain_name2nd, 
            dst_domain_name3rd 
        ), 
        created, 
        dst_page,
        src_page,
        src_domain_name1st,
        src_domain_name2nd,
        src_domain_name3rd
    )
);

但是,此 table 中有数十亿行,这对我们的硬件来说是一个问题。因此,link table 设计中的每个备用字节对我们都有很大的好处。

归一化解?

应用程序中 link table 的平均值 select 包含十分之一/数百行。在最坏的情况下,selects 包含数千行。所以使用这个 table...

来标准化问题可能是(恕我直言)明智的
CREATE TABLE IF NOT EXISTS lp_webmap.page (
   domain_name1st text,
   domain_name2nd text,
   domain_name3rd text,
   location text,
   title text,
   rank int,
   www boolean,
   update_interval smallint,
   updated timestamp,
   PRIMARY KEY (
      (domain_name1st, domain_name2nd, domain_name3rd, location),
      updated, rank, update_interval
   )
);

问题

如果我使用规范化 link 和页面 table,我需要将它们加入应用程序。那不会有问题,但是如何从页面 table 有效地 select 对应行呢?我感觉到逐个遍历 link table 和 select 相应页面行的每个结果行是无效的。

确实,JOIN 效率不高,尤其是其中一个 table 非常大。一个可能的解决方案是建立一个额外的物化视图,或者某种索引来快速搜索特定的列。这将使存储量翻倍,但无法同时实现:减少 space 消耗并提高 JOIN 查询性能。

也许您需要一个额外的硬盘驱动程序来支持新的视图或索引。

必须注意的一点是,当我们建立额外的视图或索引时,更新某些列会花费额外的时间(资源)。比如我们有两个table:订单和用户,我们通过JOIN搜索用户"jack"的所有订单。它是一个规范化版本。在实体化视图中,用户 "jack",他的所有列都合并到他的订单中以便快速访问:

primary_key, order_id, order_product, order_payment, user_name, user_age, user_favorite_color

1,       1,       iphone,       1000,       jack,       25,       blue,  
2,       3,       book,         30,         jack,       25,       blue,  
3,       6,       car,          10000,      jack,       25,       blue,  

其中 user_age、user_favorite_color 是从用户 table 中提取的冗余信息。当杰克改变他最喜欢的颜色时,所有这些记录都必须改变它们对应的列。通常一个数据库系统会启动一个后端线程来完成这个更新工作,但它仍然是一个耗时的过程,imaging jack 有数千个订单。