1

非规范化现实

在我的数据库中,我有以下非常适合我的用例的非规范化表,并且我接收数据非常快......

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

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

标准化解决方案?

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

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

问题

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

4

1 回答 1

2

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

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

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

于 2016-02-04T06:39:52.053 回答