数据库笔记(补充)——分解算法浅析

写在前面:今天笔者将会对BCNF和3NF分解算法做简要的分析,不过实际上大多数的分解用肉眼即可,以下分解算法不依赖于过多的条件可以直接讲一个满足1NF的模式分解为3NF或BCNF

BCNF 分解算法

  • 教材上关于BCNF分解算法的伪代码实现有部分印错(本科教学版)
  • 该算法的结果是一个满足BCNF的无损分解,但可能不是保持依赖的(毕竟3NF是保持依赖并且可以满足无损分解的最高范式)
  • 伪代码实现

    对满足1NF的模式R<U, F>作如下处理可分解成满足BCNF范式的模式R1, R2, ..., Rn

    result := {R};
            done := false;
            计算F+;
            while(not done) do
                  if(result中存在模式Ri不属于BCNF)
                  then begin
                          令 α→β 为一个在Ri上成立的非平凡函数依赖,满足 α→β ∈ F+, 并且 α∩β  = ∅;
                          result := (result - Ri) ∪ (Ri - β) ∪ (α, β)
                  end
                  else done := true        
    
  • 先来分析一波上面的代码吧

    1. 首先令reslut = {R}
    2. 接着计算一下F的函数闭包F+(计算函数闭包还是挺麻烦的,所以在下面判断的时候挑一个函数依赖,判断一下是否被F逻辑蕴含即可)
    3. 然后判断结果集result中是否还存在哪个模式不满足BCNF范式,如果都满足,则直接跳到步骤5,如果存在某个模式 Ri ∈ result,不满足BCNF范式,则执行步骤4
    4. 选择一个在Ri上成立的非平凡函数依赖 α→β,并且 α→β 属于 F+,并且α∩β=∅。然后将模式Ri分解成两个模式,分别为 (Ri - β) 和 (α, β)。并且将Ri从result中移除,江新得到的两个模式添加到result中。接着回到步骤3继续判断
    5. 分解完成,输出结果
  • 纸上学来终觉浅,让我们拿教材上的栗子出来刷一刷~~

    • 有模式class<U, F>, 通过上述算法,对其进行满足BCNF范式的分解
      • U = {course_id, title, dept_name, credits. sec_id, semester, year, building, room_number, capticy, time_slot_id}
      • F = {
        course_id → (title, dept_name, credits),
        (building, room_number)→capaticy,
        (course_id, sec_id, semester, year)→(building, room_number, time_slot_id)
        }
    • 首先还是看一下上面模式的候选码是什么吧(书上的栗子是直接给出来了,但是有些题可能不给,需要自己算)
      • 通过上一篇博客讲的候选码求解算法,容易求得模式class的候选码为{course_id, sec_id, semester, year}
    • 接着判断模式class是否满足BCNF范式
      • 模式R中存在依赖 course_id → (title, dept_name, credits), 但course_id并不是R的一个超码,故R不满足BCNF范式
      • 对R做如下分解
        • course(course_id, title, dept_name, credits)
        • class_1(course_id, credits. sec_id, semester, year, building, room_number, capticy, time_slot_id)
    • 继续判断,易知course是满足BCNF范式的,而course_1同理不满足BCNF范式, 继续分解
      • 找到非平凡依赖(building, room_number)→capaticy, 且其属于F
      • 对class_1分解如下
        • classroom(building, room_number, capacity)
        • section(course_id, credits. sec_id, semester, year, building, room_number, time_slot_id)
    • 检测一下发现现在模式classroom和section也满足BCNF范式了
    • OK,原来的模式class现在分解为如下三个模式
      • course(course_id, title, dept_name, credits)
      • classroom(building, room_number, capacity)
      • section(course_id, credits. sec_id, semester, year, building, room_number, time_slot_id)

3NF分解算法

以下分解算法中用到了正则覆盖的概念,这个笔者在之前的博客中也提到过,点我传送

  • 该分解算法可以保持依赖,并且是无损分解
  • 伪代码实现

     令Fc为F的正则覆盖;
     i:= 0;
     for each Fc 中的函数依赖 α→β 
             i := i + 1
             Ri := αβ;
     if 模式 Rj, j = 1, 2, ..., i 都不包含R的候选码
     then
             i := i + 1
             Ri := R的任意候选码
     /*(以下代码可选)用来移除冗余关系,如果没有冗余关系则可以不care*/ 
     repeat
             if 模式 Rj包含于另一个模式Rk中
             then
                    /*删除Rj*/
                    Rj := Ri
                     i := i - 1
     until 不再有可以删除的Rj
     return (R1, R2, ..., Ri)
    
  • 老规矩,还是先分析一下上面的伪代码

    1. 首先求出F的正则覆盖Fc(实际上就是利用Amstrong公式化简原来的函数依赖集的过程)
    2. 接着将Fc中的每一个函数依赖单独分解成一个模式,得到一个模式列表S = {R1, R2, ..., Ri}
    3. 如果上述模式列表S中的任意一个模式包含模式R的候选码,则跳到步骤5,否则执行步骤4
    4. 选取R的任意一个候选码,组成一个新的模式R', 将R'添加到模式列表S中
    5. (可选)如果模式列表中存在冗余(即某个模式被其他模式包含),则可以删除这个模式
    6. 输出S
  • 讲真,3NF分解的步骤还是很简单的,主要还是计算一下F的正则覆盖,详细栗子就不举了,下面简单提一提

    • 比如上面分析BCNF分解算法时用到的模式class, 利用上述算法分解之后可以得到和 利用BCNF算法分解一样的结果
    • 所以,神奇的事情发生了,利用3NF分解算法得到的结果可能还会满足BCNF范式
    • 实践中BCNF分解的另一种途径: 先用3NF算法分解,然后对结果中不满足BCNF范式的模式用BCNF分解算法分解,如果结果不保持依赖,则回退回3NF
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容