0

规格化现实卡桑德拉非规范化VS正常化

在我的数据库我有以下这完全符合我的使用情况非规范化的表,我收到的数据非常快...

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 
    ) 
); 

然而,该表中有数十亿行,这对我们的硬件是一个问题。因此,链接表设计中的每个备用字节对我们都有很大的好处。

Normalized solution?

从应用程序链接表中的平均选择包含十分之几/几百行。在最糟糕的情况下,选择包含数千行。因此,它可能是(恕我直言)明智使用该表正常化的问题...

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 
    ) 
); 

问题

如果我用标准化的链接和页面表,我需要加入他们的应用程序。这不会是一个问题,但如何有效地从页面表中选择相应的行?我感觉到,从链接表中遍历每个结果行并逐一选择相应的页面行是无效的。

+1

我不太确定我是否理解你的问题。但是,如果您关心的是跨分区的逻辑行重复数据,那么[静态列](http://docs.datastax.com/en/cql/3.1/cql/cql_reference/refStaticCol.html)可以帮助您而不必更改整个表格布局? – Ralf

+0

@Ralf:就是这样!顺便说一下,这是关于静态列的解释性文章:https://blogs.infosupport.com/static-columns-in-cassandra-and-their-benefits/。非常感谢你。 – Michal

回答

1

确实如此,JOIN效率不高,尤其是其中一个表非常大。一个可能的解决方案是构建一个额外的物化视图,或某种索引以快速搜索特定列。这会使存储量增加一倍,但无法实现这两者:减少空间消耗并提高JOIN查询性能。

也许你需要为新的视图或索引额外的硬件驱动程序。

必须注意的一件事是,当我们构建额外的视图或索引时,需要额外的时间(资源)来更新某些列。例如,我们有两个表格:订单和用户,我们通过JOIN搜索用户“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从用户表中提取的冗余信息。当杰克改变他最喜欢的颜色时,所有这些记录都必须改变其对应的列。通常情况下,数据库系统将启动后端步骤来执行此更新作业,但仍然是一个耗时的过程,成像插口有数千个订单。