精华内容
下载资源
问答
  • MyISAM与InnoDB索引差异

    2021-02-01 22:52:46
    -- 聚合索引 主键及唯一索引 -- 聚合索引:原则 :最左匹配原则 -- 失效原因: -- 没有匹配原则 -- 字段使用函数 -- 字段使用运算 -- 主键索引: -- 失效原因: -- 使用函数 -- join时, 字段编码不一样 -- 使用is ...
    -- 索引失效原因
    -- 聚合索引 主键及唯一索引
    -- 聚合索引:原则 :最左匹配原则
    -- 失效原因:
    -- 没有匹配原则
    -- 字段使用函数
    -- 字段使用运算
    
    -- 主键索引:
    -- 失效原因:
    -- 使用函数
    -- join时, 字段编码不一样
    -- 使用is not null
    
    -- 普通索引:
    -- 失效原因:
    -- 本身字段区分度不大
    -- 使用is null 本身字段 is not null
    
    

    -- MyISAM与InnoDB索引差异

    -- 一、
    -- MyISAM的索引与行记录是分开存储的,叫做非聚集索引
    -- 其主键索引与普通索引没有本质差异
    --      有连续的聚集区域单独存储行记录
    --      主键索引的叶子结点,存储主键,与对应行记录的指针
    --      普通索引的叶子节点,存储索引列,与对应行记录的指针
    --    斜外音:MyISAM表可以没有主键
    -- 主键索引和普通索引是两颗独立的索引B+树,通过索引列查找时,先定位到B+树的叶子节点,再通过指针定位到行记录
    -- 举个列子:
    -- t(id PK,name key, sex, flag)
    -- 插入四条记录
    -- (1,shenjian, m, A)
    -- (3,zhangsan, m, A)
    -- (5,lisi, m, A)
    -- (9,wangwu, f, B)

    ggggg

    -- 其B+树索引构造如上图所示:
    --      行记录单独存储
    --      id为PK,有一颗id的索引数,叶子指向行记录
    --      name为key,有一颗name的索引树,叶子也指向行记录

    -- 二、
    -- InnoDB的索引
    -- InnoDB的主键索引是和行记录存储在一起的,故叫做聚集索引
    --      没有单独存储行记录
    --      主键索引的叶子节点,存储主键,与对应的行记录(而不是指针)
    --    斜外音:InnoDB的PK查询是非常快的
    -- 因为这个特性:InnoDB表必须要有聚集索引
    --     (1)如果表定义了PK,则PK就是聚集索引
    --     (2)如果表没有定义PK,则第一个非空unique列是聚集索引
    --     (3)否则,InnoDB会创建一个隐藏的row-id作为聚集索引
    -- 聚集索引,也只能够有一个,因为数据行在物理磁盘上只能有一份聚集存储
    -- InnoDB的普通索引可以有多个,它与聚集索引是不同的:普通索引的叶子节点,存储主键(也不是指针)
    -- (1)不建议使用较长的列作为主键,例如char(64),因为所有的普通索引都会存储主键,会导致普通索引过于庞大
    -- (2)建议使用趋势递增的key做主键,由于数据行与索引一体,这样不至于插入记录时,有大量索引分裂,行记录移动
    -- 仍是上面的例子,只不过存储引擎换成InnoDB
    -- t(id PK,name key, sex, flag)
    -- 插入四条记录
    -- (1,shenjian, m, A)
    -- (3,zhangsan, m, A)
    -- (5,lisi, m, A)
    -- (9,wangwu, f, B)

    gggggg

    -- 其B+树索引构造如上图
    -- id为PK,行记录和索引树存储在一起
    -- name为key,有一颗name的索引树,叶子存储id
    -- 当:select * from t where name = 'lisi'

    gggggg
    -- 会先通过辅助索引定位到B+树的叶子节点得到id=5,再通过聚集索引定位到行记录
    -- 所以其实是扫描了2遍索引树

    -- 三、
    -- 总结:
    -- MyISAM和InnoDB都是用B+树来实现索引:
    -- MyISAM的索引和数据分开存储
    -- MyISAM的索引叶子存储指针,主键索引和普通索引没有太大区别
    -- InnoDB的聚集索引和数据行统一存储
    -- InnoDB的聚集索引存储数据行本身,普通索引存储主键
    -- InnoDB一定有且只有一个聚集索引
    -- InnoDB建议使用趋势递增整数作为PK,而不宜使用较长的列作为PK

    展开全文
  • 【案号】 (2019)沪73民初311号 【裁判要旨】 专利侵权案件中,组装关系唯一的组件产品外观设计比对应当遵循“整体观察、综合判断”的基本原则,二者整体视觉效果无差异或无实质性差异的,应当认定被控侵权产品...

    81270a9f0b2492a54b2afd40e5bf959e.png

      【案号】

      (2019)沪73民初311号 

      【裁判要旨】

      专利侵权案件中,组装关系唯一的组件产品外观设计比对应当遵循“整体观察、综合判断”的基本原则,二者整体视觉效果无差异或无实质性差异的,应当认定被控侵权产品落入涉案外观设计专利权利的保护范围。

      【案情简介】

      原告德贝尔公司于2018年3月17日向国家知识产权局提交了名为“衣柜床组合(03)”的外观设计专利申请(专利号:ZL201730080116.5),该专利于2017年10月27日授权公告,目前仍在有效期内。原告发现被告在多个门店及网上生产、销售和许诺销售涉案侵权产品,故诉至法院,请求法院判令被告立即停止实施侵犯原告专利权的行为,包括停止生产、销售和许诺销售涉案侵权产品,并赔偿原告经济损失20万元及合理支出2万元。

      被告锯斧公司答辩称,被控侵权产品没有落入涉案专利权利要求保护范围,理由如下:被控侵权产品与涉案专利之间存在显著区别,整体视觉效果明显不同。区别1为涉案专利中有两个护栏,分别位于床头以及床右侧,均呈“日”字型,被控侵权产品床头无护栏,靠垫需要靠墙放置,否则容易在人一侧倾斜,实际使用时有席梦思,不会发生倾斜,侧面护栏的形状与涉案专利不同;区别2为涉案专利衣柜门上的拉手为“双L”型,拉手的形状是涉案专利所在系列产品中的一个显著的“视觉符号”,所占面积比普通笔记本还大,占产品较大的视觉比重,被控侵权产品衣柜门上没有“双L”型的拉手,是两个一大一小的圆;区别3为涉案专利的靠垫是平整、方正的,被诉侵权产品的靠垫带有明显分割效果,四个角都是圆形,有立体感,显得圆润;区别4为涉案专利的步梯只能放在右侧,被诉侵权产品的楼梯可以放在左侧也可以放在右侧,形状有区别;区别5为涉案专利矮柜的拉手棱角分明,被诉侵权产品矮柜拉手圆润细巧。被诉侵权产品与涉案专利的相同点已被公开或属于常规设计。被诉侵权产品与涉案专利均包括:楼梯、书桌、矮柜、储物格、床、衣柜,其中楼梯、书桌、矮柜、储物格均属于已被公开的设计要点,床板和衣柜属于常规的设计要点,即使涉案专利与被诉侵权产品有相同之处,也是技术功能的必然结果。涉案专利区别于现有设计的区别设计特征为矮柜把手竖直方向结构、床护栏为“日”形结构以及床柜把手“L”形结构,但被诉侵权产品未包含涉案专利区别于现有设计的任何一个设计特征。

      上海知识产权法院经审理认为,被控侵权产品与涉案专利均为家具,属于相同种类的产品。虽然被控侵权产品与涉案专利存在部分细节不同,但二者各部件的组合方式整体相同,按照“整体观察、综合判断”的比对标准,二者的整体视觉效果无实质性差异,被控侵权产品落入涉案外观设计专利权利保护范围。

      据此,上海知识产权法院判决被告锯斧公司停止侵权,并赔偿损失22万元。双方均未上诉,目前该案已生效。

      【法官评析】

      专利侵权案件中,组装关系唯一的组件产品外观设计比对,要遵循“整体观察、综合判断”的基本原则,本案也为同类案件的审理提供了指引。

      被控侵权产品与涉案专利产品属于同类产品,均为家具。涉案专利包括楼梯、书桌、矮柜等多个组件。对于多组件产品,专利分为成套产品、无组装关系的组件产品以及组装关系唯一的组件产品。根据《专利审查指南》,对于成套产品应当在其中每件产品的视图名称前以阿拉伯数字顺序编号标注,并在编号前加“套件”字样。对于无组装关系或者组装关系不唯一的组件产品,应当提交各构件的视图,并在每个构件的视图名称前以阿拉伯数字顺序编号标注,并在编号前加“组件”字样。对于组装关系唯一的组件产品,应当提交组合状态的产品视图。涉案专利属于组装关系唯一的组件产品。将已公开的设计元素进行组合,产生的整体外观设计区别于现有设计,应受到专利法的保护。

      对组装关系唯一的组件产品外观设计侵权比对,法院依照“整体观察、综合判断”的比对标准进行。在本案勘验过程中,完成搭建之后将被控侵权产品与涉案专利进行对比,二者均由床、储物格、推拉桌、矮柜、衣柜、储物楼梯组成,分为上下两层,床板下方分为三部分,左上为储物格,左下镂空可收纳推拉桌和矮柜,右下方为双开门衣柜,床板右侧为4级储物楼梯。二者的不同之处的确存在四点,但是床柜组合产品的设计空间较大,组合方式多样,虽然被控侵权产品与涉案专利存在上述细节不同,但二者各部件的组合方式整体相同,按照“整体观察、综合判断”的比对标准,二者的整体视觉效果无实质性差异,被控侵权产品落入涉案外观设计专利权利保护范围。

      被告认为,涉案专利的步梯只能放在右侧,被控侵权产品的楼梯可以放在左侧也可以放在右侧,形状有区别。法院认为,在案物证的步梯放在右侧是证物出厂时的安排。其次,虽然被告产品仅需简单调整安装位置即可按照步梯在左侧的设计进行生产,但这种简单的对称调整对产品的整体视觉效果不会造成实质性差别。

      被告还认为,被控侵权产品系定制产品,购买方参与了被控侵权产品的设计。在案证据显示,尽管在案物证的购买者对产品的尺寸、规格提出了个性化要求,但未改变产品的整体布局、各个组件以及各个组件之间的摆放,整体视觉效果未因此而改变。因此,被告以涉案物证为定制产品为由,提出仅在案物证侵权的观点,法院不予采纳。(上海知识产权法院 商建刚)

    (本文仅代表作者个人观点)

    (文章来源:中国知识产权报 原标题:组装关系唯一的组件产品外观设计侵权比对规则——评德贝尔公司诉锯斧公司侵害外观设计专利权纠纷案)

    (责任编辑:吕可珂  编辑:高云翔  审校:崔静思)

    (中国知识产权报独家稿件,未经授权不得转载)

    23ef2d768ca215613875f9bf054f4ef6.png

    展开全文
  • 当我们成为低层次的东西少趋于正常,我们许多人并不完全理解堆和栈实际发生的编译,就是静态和动态类型等之间的差异我不是说所有的程序员不知道这些事情 - 我只是觉得,有时候是值得回过头来这样的老学校的事情。...

    stack栈
    heap堆

    我们使用更多,更先进的编程语言,使我们能够写更少的代码,并获得优异的成就。对于支付。当我们成为低层次的东西少趋于正常,我们许多人并不完全理解堆和栈实际发生的编译,就是静态和动态类型等之间的差异我不是说所有的程序员不知道这些事情 - 我只是觉得,有时候是值得回过头来这样的老学校的事情。
    今天,我们将谈论一件唯一的话题:栈和堆。且堆栈,和很多关注到不同的位置,其中,存储器管理,但这种管理策略是根本不同的。


    栈 - 这是对每个线程创建的内存区域。他的作品以LIFO(后入先出),即加入到堆栈存储器的最后一块将是排在第一位堆栈撤出。每次函数声明一个新的变量,它被添加到堆栈中,以及当可变滴出的范围(例如,当函数结束时),它会自动从堆栈中删除。当堆栈变量被释放,该存储区可用于其它堆栈变量。

    由于这种性质栈存储器管理是很合乎逻辑的,简单到CPU上执行的;这导致高的速度,特别是,由于周期时间更新字节堆栈是很小的,即这个字节是可能依赖于处理器的高速缓存中。然而,在这样的控制的一个严格的形式也有其缺点。堆栈大小 - 是一个固定值,和过量的分配给存储器堆的限制将导致堆栈溢出。在创建流时指定的尺寸,并且每个变量具有的取决于数据的类型的最大尺寸。这使您可以限制一些变量(例如,整数)的规模,并被迫提前申报更复杂的数据类型的大小(如数组),因为堆栈不允许他们去改变它。此外,变量,位于堆栈上总是本地。因此,栈可以让你更有效地管理内存 - 但如果你需要使用动态数据结构和全局变量,这是得关注的堆。

    堆 - 一个存储器存储,也设在RAM中,其允许的存储器的动态分配,并且不会在堆叠的原理工作:它仅仅是为你的变量仓库。时分配的堆存储器区域,用于存储一个变量,它可以应用不仅在信息流中,而且在整个应用程序。由所述全局变量来确定。这些应用程序分配内存后的区域将被释放。当你运行应用程序堆大小设置,但不像栈,它只是身体上有限的,它可以让你创建动态的变量。
    你用一束参考,通常被称为指针交互 - 是变量,其值是其它变量的地址。创建一个指针,指向在堆上的存储器位置,该设置变量的初始值和告诉程序访问此值。由于CPU堆不参与在它的控制的动态特性;在没有垃圾收集(C,C ++)开发的语言需要手动释放不再需要的内存区域。如果不这样做,有可能泄漏和存储器碎片,这显著减慢堆。
    在与堆栈相比,堆是慢的,因为变量是散射存储器,并且不坐在堆栈的顶部。不正确的内存管理,堆减慢它的操作;然而,这并没有减弱它的重要性 - 如果你需要一个充满活力和全局变量的工作,使用堆。

    结论

    所以,你已经结识了栈和堆的概念。总之,堆栈 - 它是非常快的存储器存储,在后进先出的原则工作和由处理器控制的。但这些优点导致堆栈的尺寸限制,并且用于产生值的特殊方法。为了避免这些限制,您可以用一束 - 它允许你创建动态和全局变量 - 但必须管理内存或垃圾收集,或程序员,和一堆运行速度较慢的。


    展开全文
  • 在互联网上,利用上层软件来完成这个统一,也就是在ip协议层提供一种统一的地址格式,在统一管理下进行分配,保证每一个地址对应一台网络上的主机或设备,这样物理地址间的差异就被ip层屏蔽了,这个地址就是IP地址。...
  • 单个物理维度可以被事实表多次引用,每个引用连接逻辑上存在差异的角色维度。例如,事实表可以有多个日期,每个日期通过外键引用不同的日期维度,原则上每个外键表示不同的日期维度视图,这样引用具有不同的含义。...
            单个物理维度可以被事实表多次引用,每个引用连接逻辑上存在差异的角色维度。例如,事实表可以有多个日期,每个日期通过外键引用不同的日期维度,原则上每个外键表示不同的日期维度视图,这样引用具有不同的含义。这些不同的维度视图具有唯一的代理键列名,被称为角色,相关维度被称为角色扮演维度。
            当一个事实表多次引用一个维度表时会用到角色扮演维度。例如,一个销售订单有一个是订单日期,还有一个请求交付日期,这时就需要引用日期维度表两次。
            我们期望在每个事实表中设置日期维度,因为总是希望按照时间来分析业务情况。在事务型事实表中,主要的日期列是事务日期,例如,订单日期。有时会发现其它日期也可能与每个事实关联,例如,订单事务的请求交付日期。每个日期应该成为事实表的外键。
            本篇说明两类角色扮演维度的实现,分别是表别名和数据库视图。表别名是在SQL语句里引用维度表多次,每次引用都赋予维度表一个别名。而数据库视图,则是按照事实表需要引用维度表的次数,建立相同数量的视图。我先修改销售订单数据库模式,添加一个请求交付日期字段,并对数据抽取和装载脚本做相应的修改。这些表结构修改好后,插入测试数据,演示别名和视图在角色扮演维度中的用法。

    一、修改数据库模式


    1. 修改源库表结构

            执行下面的脚本,给源库中销售订单表sales_order增加request_delivery_date字段。
    use source;    
    alter table sales_order add request_delivery_date datetime after order_date ;

    2. 修改数据仓库表结构

    -- 修改外部表
    drop external table ext.sales_order;  
    create external table ext.sales_order    
    (     
      order_number int,        
      customer_number int,        
      product_code int,        
      order_date timestamp, 
      request_delivery_date timestamp,   
      entry_date timestamp,        
      order_amount decimal(10 , 2 ),    
      order_quantity int   
    )      
    location ('pxf://mycluster/data/ext/sales_order?profile=hdfstextsimple')      
      format 'text' (delimiter=e',', null='null');    
    
    comment on table ext.sales_order is '销售订单外部表';    
    comment on column ext.sales_order.order_number is '订单号';    
    comment on column ext.sales_order.customer_number is '客户编号';    
    comment on column ext.sales_order.product_code is '产品编码';    
    comment on column ext.sales_order.order_date is '订单日期'; 
    comment on column ext.sales_order.request_delivery_date is '请求交付日期';  
    comment on column ext.sales_order.entry_date is '登记日期';    
    comment on column ext.sales_order.order_amount is '销售金额';   
    comment on column ext.sales_order.order_quantity is '销售数量';  
    
    -- 修改rds.sales_order
    alter table rds.sales_order add column request_delivery_date timestamp default null; 
    comment on column rds.sales_order.request_delivery_date is '请求交付日期';  
    
    -- 修改tds.sales_order_fact
    alter table tds.sales_order_fact add column request_delivery_date_sk bigint default null; 
    comment on column tds.sales_order_fact.request_delivery_date_sk is '请求交付日期维度代理键';  
    comment on column tds.sales_order_fact.order_date_sk is '订单日期维度代理键';
            增加列的过程已经在“HAWQ数据仓库实践(六)——增加列”(http://blog.csdn.net/wzy0623/article/details/72651785)详细讨论过。HAWQ不支持给外部表增加列,因此需要重建表。在销售订单外部表上增加请求交付日期字段,数据类型是timestamp,对应源库表上的datetime类型。注意外部表中列的顺序要和源表中列定义的顺序保持一致。
            RDS和TDS中的内部表直接使用ALTER TABLE语句增加请求交付日期列。因为HAWQ的ADD COLUMN不支持after语法,新增的字段会加到所有已存在字段的后面。修改后数据仓库模式如图1所示。
    图1

            从图中可以看到,销售订单事实表和日期维度表之间有两条连线,表示订单日期和请求交付日期都是引用日期维度表的外键。注意,虽然图中显示了表之间的关联关系,但HAWQ中并不支持主外键数据库约束。

    二、修改定期数据装载函数

    create or replace function fn_regular_load ()        
    returns void as        
    $$        
    declare        
        -- 设置scd的生效时间      
        v_cur_date date := current_date;          
        v_pre_date date := current_date - 1;      
        v_last_load date;      
    begin      
        -- 分析外部表      
        analyze ext.customer;      
        analyze ext.product;      
        analyze ext.sales_order;      
          
        -- 将外部表数据装载到原始数据表      
        truncate table rds.customer;        
        truncate table rds.product;       
          
        insert into rds.customer select * from ext.customer;       
        insert into rds.product select * from ext.product;      
        insert into rds.sales_order 
    	select order_number,
               customer_number,
               product_code,
               order_date,
               entry_date,
               order_amount,
               order_quantity,
               request_delivery_date 
    	  from ext.sales_order;      
              
        -- 分析rds模式的表      
        analyze rds.customer;      
        analyze rds.product;      
        analyze rds.sales_order;      
          
        -- 设置cdc的上限时间      
        select last_load into v_last_load from rds.cdc_time;      
        truncate table rds.cdc_time;      
        insert into rds.cdc_time select v_last_load, v_cur_date;      
          
        -- 装载客户维度      
        insert into tds.customer_dim      
        (customer_number,      
         customer_name,      
         customer_street_address,      
         customer_zip_code,      
         customer_city,      
         customer_state,    
         shipping_address,     
         shipping_zip_code,     
         shipping_city,     
         shipping_state,      
         isdelete,      
         version,      
         effective_date)      
        select case flag       
                    when 'D' then a_customer_number      
                    else b_customer_number      
                end customer_number,      
               case flag       
                    when 'D' then a_customer_name      
                    else b_customer_name      
                end customer_name,      
               case flag       
                    when 'D' then a_customer_street_address      
                    else b_customer_street_address      
                end customer_street_address,      
               case flag       
                    when 'D' then a_customer_zip_code      
                    else b_customer_zip_code      
                end customer_zip_code,      
               case flag       
                    when 'D' then a_customer_city      
                    else b_customer_city      
                end customer_city,      
               case flag       
                    when 'D' then a_customer_state      
                    else b_customer_state      
                end customer_state,      
               case flag       
                    when 'D' then a_shipping_address      
                    else b_shipping_address      
                end shipping_address,    
               case flag       
                    when 'D' then a_shipping_zip_code      
                    else b_shipping_zip_code      
                end shipping_zip_code,      
               case flag       
                    when 'D' then a_shipping_city      
                    else b_shipping_city      
                end shipping_city,      
               case flag       
                    when 'D' then a_shipping_state      
                    else b_shipping_state      
                end shipping_state,    
               case flag       
                    when 'D' then true      
                    else false      
                end isdelete,      
               case flag       
                    when 'D' then a_version      
                    when 'I' then 1      
                    else a_version + 1      
                end v,      
               v_pre_date      
          from (select a.customer_number a_customer_number,      
                       a.customer_name a_customer_name,      
                       a.customer_street_address a_customer_street_address,      
                       a.customer_zip_code a_customer_zip_code,      
                       a.customer_city a_customer_city,      
                       a.customer_state a_customer_state,     
                       a.shipping_address a_shipping_address,      
                       a.shipping_zip_code a_shipping_zip_code,      
                       a.shipping_city a_shipping_city,      
                       a.shipping_state a_shipping_state,     
                       a.version a_version,      
                       b.customer_number b_customer_number,      
                       b.customer_name b_customer_name,      
                       b.customer_street_address b_customer_street_address,      
                       b.customer_zip_code b_customer_zip_code,      
                       b.customer_city b_customer_city,      
                       b.customer_state b_customer_state,     
                       b.shipping_address b_shipping_address,      
                       b.shipping_zip_code b_shipping_zip_code,      
                       b.shipping_city b_shipping_city,      
                       b.shipping_state b_shipping_state,     
                       case when a.customer_number is null then 'I'      
                            when b.customer_number is null then 'D'      
                            else 'U'       
                        end flag      
                  from v_customer_dim_latest a       
                  full join rds.customer b on a.customer_number = b.customer_number       
                 where a.customer_number is null -- 新增      
                    or b.customer_number is null -- 删除      
                    or (a.customer_number = b.customer_number       
                        and not       
                               (coalesce(a.customer_name,'') = coalesce(b.customer_name,'')       
                            and coalesce(a.customer_street_address,'') = coalesce(b.customer_street_address,'')       
                            and coalesce(a.customer_zip_code,0) = coalesce(b.customer_zip_code,0)      
                            and coalesce(a.customer_city,'') = coalesce(b.customer_city,'')       
                            and coalesce(a.customer_state,'') = coalesce(b.customer_state,'')    
                            and coalesce(a.shipping_address,'') = coalesce(b.shipping_address,'')       
                            and coalesce(a.shipping_zip_code,0) = coalesce(b.shipping_zip_code,0)      
                            and coalesce(a.shipping_city,'') = coalesce(b.shipping_city,'')       
                            and coalesce(a.shipping_state,'') = coalesce(b.shipping_state,'')    
                            ))) t      
                 order by coalesce(a_customer_number, 999999999999), b_customer_number limit 999999999999;      
       
        -- 重载PA客户维度    
        truncate table pa_customer_dim;      
        insert into pa_customer_dim      
        select customer_sk,     
               customer_number,        
               customer_name,        
               customer_street_address,        
               customer_zip_code,        
               customer_city,        
               customer_state,      
               isdelete,     
               version,      
               effective_date,      
               shipping_address,   
               shipping_zip_code,  
               shipping_city,  
               shipping_state     
          from customer_dim      
         where customer_state = 'pa';     
      
        -- 装载产品维度      
        insert into tds.product_dim      
        (product_code,      
         product_name,      
         product_category,           
         isdelete,      
         version,      
         effective_date)      
        select case flag       
                    when 'D' then a_product_code      
                    else b_product_code      
                end product_code,      
               case flag       
                    when 'D' then a_product_name      
                    else b_product_name      
                end product_name,      
               case flag       
                    when 'D' then a_product_category      
                    else b_product_category      
                end product_category,      
               case flag       
                    when 'D' then true      
                    else false      
                end isdelete,      
               case flag       
                    when 'D' then a_version      
                    when 'I' then 1      
                    else a_version + 1      
                end v,      
               v_pre_date      
          from (select a.product_code a_product_code,      
                       a.product_name a_product_name,      
                       a.product_category a_product_category,      
                       a.version a_version,      
                       b.product_code b_product_code,      
                       b.product_name b_product_name,      
                       b.product_category b_product_category,                     
                       case when a.product_code is null then 'I'      
                            when b.product_code is null then 'D'      
                            else 'U'       
                        end flag      
                  from v_product_dim_latest a       
                  full join rds.product b on a.product_code = b.product_code       
                 where a.product_code is null -- 新增      
                    or b.product_code is null -- 删除      
                    or (a.product_code = b.product_code       
                        and not       
                               (a.product_name = b.product_name       
                            and a.product_category = b.product_category))) t      
                 order by coalesce(a_product_code, 999999999999), b_product_code limit 999999999999;      
          
        -- 装载order维度        
        insert into order_dim (order_number, version, effective_date)       
        select t.order_number, t.v, t.effective_date        
          from (select order_number, 1 v, order_date effective_date         
                  from rds.sales_order, rds.cdc_time         
                 where entry_date >= last_load and entry_date < current_load) t;      
          
        -- 装载销售订单事实表        
        insert into sales_order_fact        
        select order_sk,        
               customer_sk,        
               product_sk,        
               e.date_sk,      
               e.year * 100 + e.month,           
               order_amount,    
               order_quantity,
               f.date_sk		   
          from rds.sales_order a,        
               order_dim b,        
               v_customer_dim_his c,        
               v_product_dim_his d,        
               date_dim e, 
               date_dim f,		   
               rds.cdc_time g        
         where a.order_number = b.order_number        
           and a.customer_number = c.customer_number        
           and a.order_date >= c.effective_date      
           and a.order_date < c.expiry_date         
           and a.product_code = d.product_code        
           and a.order_date >= d.effective_date      
           and a.order_date < d.expiry_date         
           and date(a.order_date) = e.date  
           and date(a.request_delivery_date) = f.date  
           and a.entry_date >= g.last_load and a.entry_date < g.current_load;                    
          
        -- 分析tds模式的表      
        analyze customer_dim;      
        analyze product_dim;      
        analyze order_dim;      
        analyze sales_order_fact;      
          
        -- 更新时间戳表的last_load字段        
        truncate table rds.cdc_time;      
        insert into rds.cdc_time select v_cur_date, v_cur_date;      
          
    end;        
    $$        
    language plpgsql;

            函数做了以下两点修改:
    • 在装载rds.sales_order时显式指定了列的顺序,因为外部表与内部表列的顺序不一致。
    • 在装载销售订单事实表时,关联了日期维度表两次,分别赋予别名e和f。事实表和两个日期维度表关联,取得日期代理键。e.date_sk表示订单日期代理键,f.date_sk表示请求交付日期的代理键。

    三、测试


    1. 在源库中生成测试数据

            执行下面的SQL脚本在源库中增加三个带有交货日期的销售订单。
    use source;  
    /*** 新增订单日期为昨天的3条订单。***/      
    set @start_date := unix_timestamp(date_add(current_date, interval -1 day));     
    set @end_date := unix_timestamp(current_date);   
    
    drop table if exists temp_sales_order_data;      
    create table temp_sales_order_data as select * from sales_order where 1=0;       
          
    set @order_date := from_unixtime(@start_date + rand() * (@end_date - @start_date));   
    set @request_delivery_date := from_unixtime(unix_timestamp(date_add(current_date, interval 5 day)) + rand() * 86400);         
    set @amount := floor(1000 + rand() * 9000);    
    set @quantity := floor(10 + rand() * 90);    
    insert into temp_sales_order_data 
    values (126, 1, 1, @order_date, 
    @request_delivery_date, @order_date, @amount, @quantity);      
    
    set @order_date := from_unixtime(@start_date + rand() * (@end_date - @start_date)); 
    set @request_delivery_date := from_unixtime(unix_timestamp(date_add(current_date, interval 5 day)) + rand() * 86400);      
    set @amount := floor(1000 + rand() * 9000);    
    set @quantity := floor(10 + rand() * 90);    
    insert into temp_sales_order_data 
    values (127, 2, 2, @order_date, 
    @request_delivery_date, @order_date, @amount, @quantity);      
    
    set @order_date := from_unixtime(@start_date + rand() * (@end_date - @start_date));
    set @request_delivery_date := from_unixtime(unix_timestamp(date_add(current_date, interval 5 day)) + rand() * 86400);       
    set @amount := floor(1000 + rand() * 9000);    
    set @quantity := floor(10 + rand() * 90);    
    insert into temp_sales_order_data 
    values (128, 3, 3, @order_date, 
    @request_delivery_date, @order_date, @amount, @quantity);      
    
    insert into sales_order      
    select null,customer_number,product_code,order_date,
    request_delivery_date,entry_date,order_amount,order_quantity 
    from temp_sales_order_data order by order_date;        
    commit ;

    2. 执行定期装载函数并查看结果

    ~/regular_etl.sh
            使用下面的查询验证结果。
    select a.order_sk, request_delivery_date_sk, c.date  
      from sales_order_fact a, date_dim b, date_dim c  
     where a.order_date_sk = b.date_sk   
       and a.request_delivery_date_sk = c.date_sk ;
            查询结果如图2所示。
    图2

            可以看到只有三个新的销售订单具有request_delivery_date_sk值,6360对应的日期是2017年5月30日。

    四、使用角色扮演维度查询


    1. 使用表别名查询

    select order_date_dim.date order_date,    
            request_delivery_date_dim.date request_delivery_date,    
            sum(order_amount),count(*)    
      from sales_order_fact a,
            date_dim order_date_dim,    
            date_dim request_delivery_date_dim    
     where a.order_date_sk = order_date_dim.date_sk    
       and a.request_delivery_date_sk = request_delivery_date_dim.date_sk    
     group by order_date_dim.date , request_delivery_date_dim.date    
     order by order_date_dim.date , request_delivery_date_dim.date;

    2. 使用视图查询

    -- 创建订单日期视图  
    create view v_order_date_dim 
    (order_date_sk, 
     order_date, 
     month, 
     month_name,  
     quarter, 
     year) 
    as select * from date_dim;    
    -- 创建请求交付日期视图
    create view v_request_delivery_date_dim
    (request_delivery_date_sk, 
     request_delivery_date, 
     month, 
     month_name, 
     quarter, 
     year)   
    as select * from date_dim;  
    -- 查询
    select order_date,request_delivery_date,sum(order_amount),count(*)    
      from sales_order_fact a,v_order_date_dim b,v_request_delivery_date_dim c    
     where a.order_date_sk = b.order_date_sk    
       and a.request_delivery_date_sk = c.request_delivery_date_sk    
     group by order_date , request_delivery_date    
     order by order_date , request_delivery_date;

            上面两种实现方式是等价的。结果如图3所示。


    图3

            尽管不能连接到单一的日期维度表,但可以建立并管理单独的物理日期维度表,然后使用视图或别名建立两个不同日期维度的描述。注意在每个视图或别名列中需要唯一的标识。例如,订单日期属性应该具有唯一标识order_date以便与请求交付日期request_delivery_date区别。别名与视图在查询中的作用并没有本质的区别,都是为了从逻辑上区分同一个物理维度表。许多BI工具也支持在语义层使用别名。但是,如果有多个BI工具,连同直接基于SQL的访问,都同时在组织中使用的话,不建议采用语义层别名的方法。当某个维度在单一事实表中同时出现多次时,则会存在维度模型的角色扮演。基本维度可能作为单一物理表存在,但是每种角色应该被当成标识不同的视图展现到BI工具中。


    五、一种有问题的设计

            为处理多日期问题,一些设计者试图建立单一日期维度表,该表使用一个键表示每个订单日期和请求交付日期的组合,例如:
    create table date_dim (date_sk int, order_date date, delivery_date date);
    create table sales_order_fact (date_sk int, order_amount int);
            这种方法存在两个方面的问题。首先,如果需要处理所有日期维度的组合情况,则包含大约每年365行的清楚、简单的日期维度表将会极度膨胀。例如,订单日期和请求交付日期存在如下多对多关系:
    订单日期  		请求交付日期
    2017-05-26 		2017-05-29
    2017-05-27 		2017-05-29
    2017-05-28 		2017-05-29
    2017-05-26 		2017-05-30
    2017-05-27 		2017-05-30
    2017-05-28 		2017-05-30
    2017-05-26 		2017-05-31
    2017-05-27 		2017-05-31
    2017-05-28 		2017-05-31
            如果使用角色扮演维度,日期维度表中只需要2017-05-26到2017-05-31六条记录。而采用单一日期表设计方案,每一个组合都要唯一标识,明显需要九条记录。当两种日期及其组合很多时,这两种方案的日期维度表记录数会相去甚远。
            其次,合并的日期维度表不再适合其它经常使用的日、周、月等日期维度。日期维度表每行记录的含义不再指唯一一天,因此无法在同一张表中标识出周、月等一致性维度,进而无法简单地处理按时间维度的上卷、聚合等需求。
    展开全文
  • 主键自动创建唯一索引 频繁作为查询条件的字段 查询中与其他表关联的字段 查询中排序的字段 查询中统计或分组字段 1.1.2 不适合使用索引的场景 频繁更新的字段 where 条件中用不到的字段 表记录太少 经常增删改的表 ...
  • MySQL索引解析

    2019-07-04 02:41:52
    6.唯一索引和普通索引的性能差异 索引的出现是为了提高查询效率,但是实现索引的方式却有很多种,本质上就是用于提高读写效率的数据结构,主要有哈希表、有序数组和搜索树。这里主要讲MyISAM和InnoDB两个存储引擎的...
  • 歌声提取器

    2014-01-03 11:20:54
     「歌声提取器」,是利用CD上的音乐与伴奏,通过轨道之间的差异,试图抽出唯一的人声。  原则上,只有原版音乐减去原伴奏 才是正确的,但它似乎不那么容易实践。尽管如此,靠的是什么 因为有事情去写条款或护理...
  • 程序员的SQL金典.rar

    2009-03-29 02:23:23
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 程序员的SQL金典1-8

    2011-05-20 18:09:38
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 程序员的SQL金典7-8

    2011-05-20 18:30:04
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 程序员的SQL金典6-8

    2011-05-20 18:29:34
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 程序员的SQL金典5-8

    2011-05-20 18:13:41
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 程序员的SQL金典4-8

    2011-05-20 18:12:51
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 程序员的SQL金典3-8

    2011-05-20 18:11:59
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 程序员的SQL金典2-8

    2011-05-20 18:11:12
     6.2.2 唯一约束  6.2.3 CHECK约束  6.2.4 主键约束  6.2.5 外键约束 第7章 表连接  7.1 表连接简介  7.2 内连接(INNER JOIN)  7.3 不等值连接  7.4 交叉连接  7.5 自连接  7.6 外部连接  7.6.1 左外部...
  • 其他的差异主要是在应用上而不是在原则上。所有组织 的管理者,都要面对决策,要做人事决策,而人的问题几乎是一样的。所有组织的管理者都面对沟通问题,管理者要花大量的时间 与上司和下属进行沟通。在所有组织中,...
  • 这一版的更新也反映了其他语言的发展,深入讲解了Sun的java.util.regex,并特别提到了Java1.4.2和Java1.5/1.6之间的众多差异。 本书的内容: ·各种语言和工具的功能比较 ·正则引擎的工作原理 ·优化(能节省大量...
  • 10. 数据约束:数据结构备注中PK为监管部门作为唯一性约束的参考条件,含有多个PK的,表示联合主键的参考,并不作为主外键唯一性约束的条件,可根据数据实际使用用途情况作出调整。 11. 数据项报送:《规范》中所有...
  • SQL性能优化

    2014-12-20 10:21:26
    1 性能优化 1.1 避免频繁 commit,尤其...说明:除非是单据的单号,要求必须是唯一,并且依据流水号不可以跳号,不然在大量交易的表格中,不在乎跳耗时,要取得唯一的Primary Key 建议使用Oracle Sequence这样速度会较...

空空如也

空空如也

1 2 3 4 5
收藏数 91
精华内容 36
关键字:

唯一差异原则