動機

突然想起來 有這種東西 就來重看一下

相依(叫參照或許比較好)

可以把table想成某種dict, 而這個dict的key是一種pair, 而pair丟到dict中,如果拿到只有一筆資料就是一種鍵 也就是相依

像是用學號去找就只會找到一個學生

一般來說會有許多種pair都可以拿到只有一筆資料,這個叫超鍵 把超鍵的項目去掉,去到不能再去掉就是候選鍵(對,這也可能有許多組合,學號、身分證) 從候選鍵選一種喜歡的就是主鍵

大概寫成code(pseudo-python)

table = {...}

superKey = [tup for tup in all_combination(table.keys()) if len(table[tup]) == 1].sort(key=lambda tup: len(tup))

def candicateKey():
    keysIter = iter(superKey)
    yield next(keysIter)
    keys = candicateKey()
    for tup in keys:
        yielded = False
        for possible_key in keysIter:
            if tup.is_subset(possible_key):
	        continue
	    else:
	        yield possible_key
		    yielded = True
        if not yielded:
	        raise StopIteration()
	         

1NF

就是為了因應row不能放可變長度的array所以要把Item轉90度,也因為這樣我們有了後面的種種NF

至於那些新增、刪除與修改異常都是因為當初存可變長度的array的row不是struct 所以不可以用pointer直接改,要轉90度重複寫下原本struct的其他資料

2NF

其實接下去的NF都是把可以推導出來(或是叫找出)的item抽出去

  • 看主鍵外的資料與主鍵的關係
    • 部分相依
      • 只有與主鍵的單個項目相依
    • 完全相依
      • 與主鍵的所有項目相依

2NF就是把(針對主鍵的)部分相依抽出去,像A,B是主鍵

{A,B} -> {D, E, F} {B} -> {D, F}

D,F就是對B部分相依

像是有一個成績table student ID, course ID, name, 總排名, grade

name與總排名很明顯只與student ID有關,所以可以抽出去

3NF

現在可依透過所有主鍵去filter出所有資料 3NF要看其他欄位能不能filter出其他資料

換言之,就是看主鍵外的資料有沒有與主鍵外的資料相依

這是在公三小?

像B是主鍵 {B} -> {D, F} {D} -> {F} 這樣可以把F抽出去,這就是3NF想做的

前面分出來的table student ID,name, 總排名 在此name可以filter出總排名

所以還要再把name割出來

遞移相依: 像上面F就是透過D相依B,這就是遞移相依

2NF與3NF差在?

2NF是處理部分主鍵的相依 3NF是處理非主鍵的相依

但一般處理相依,或者應該說是分類cloumn,都是直接把有關的放在一起 所以,2NF與3NF看起來很像,因為都是處理重複的相依,但是兩者的範疇不同 同時順序也不一定或是先2NF再3NF

BCNF

看有沒有不為主鍵的項目可以相依到主鍵的某個項目? 有的話就抽出去把cycle打斷

假設 {A,B}是主鍵 但 {A, B} -> {C} {C} -> {B} 這樣就是一個cycle的fu

所以可以拆掉,有不同的拆法

  1. {A,C} 為主鍵,把{B,C}拉到另一張表
  2. {A,B} 為主鍵,把{B,C}拉到另一張表