관계 데이터베이스에서 릴레이션(Relation)의 튜플(Tuple)을 유일하게 식별할 수 있는 속성(Attribute) 또는 속성의 집합 중, 다음 두 성질을 만족하는 것을 후보 키(Candidate Key)라고 한다.
유일성(uniqueness) : 릴레이션에 있는 모든 튜플에 대해 유일하게 식별되어야 한다.
최소성(minimality) : 유일성을 가진 키를 구성하는 속성(Attribute) 중 하나라도 제외하는 경우 유일성이 깨지는 것을 의미한다. 즉, 릴레이션의 모든 튜플을 유일하게 식별하는 데 꼭 필요한 속성들로만 구성되어야 한다.
제이지를 위해, 아래와 같은 학생들의 인적사항이 주어졌을 때, 후보 키의 최대 개수를 구하라.
그냥 구현 문제
아니 11시부터 12시지나기 전까지 커밋할려고(1일 1커밋 목표 ^8^) 급하게 풀긴했는데
저 tp 배열, 즉 후보키의 속성별로 묶을려하는 저 한줄이 빠르게 안 떠올라서 굳이 굳이 돌아서 생각나는 대로 적으니까 시간이 더 걸린 것 같다. + (set.issubset() 함수도 몰라서 또 돌아가다 짜증나서 구글링 중 저 함수 찾음)
처음 보자마자 어떻게 풀어야할 지 눈에 보이니까 세세한 부분(한 행씩 후보키들의 속성별 묶어주기= 인덱스처럼 한번 헷갈리면 지구 끝까지 헷갈리는 것)을 길게 생각하지 않으니까 또 쓸데없는 시간을 날렸다. 어제도 이러지 말자 다짐했눈데 ㅎ0ㅎ..
⭐그냥 구현 -> 조합활용
예전이랑 똑같네 쓸데없이 시간날리기 ㅎ,,
+)set.issubset() 함수 또 기억못함 ㅎㅎ
생각보다 쉬운편인데 왜 정답률이 39% 밖에 안되냐
main함수
for i in range(1,len(relation[0])+1):
이 부분을 제대로 설정안해서 -0-
첫번째 오류
열을 기준으로 하는거라 열이 개수인 len(relation[0])를 해줘야하는데
relation[0]이 아니라 relation 써서 인덱스 오류 졸라뜸 -0-
uniqueness이 함수에서 자꾸 인덱스 오류 떠서 엥 여기가 문젠가 하고
여기서 다시 디버깅해보느라 좀 걸렸음.
두번째 오류
테케 5,6,8,21 이것들 틀렸으면 전체 행이 후보키일 때 경우를 안해준 거임.
나 같은 경우 len(relation[0])+1)에서 +1 안해줌
처음 코드
from itertools import combinations
def dis(c,relation):
cals = [[j[i] for j in relation] for i in c]
set_ = []
for i in range(len(relation)):
temp = []
for j in range(len(cals)):
temp.append(cals[j][i])
set_.append(tuple(temp))
if len(set_) == len(set(set_)): return 1
else: return 0
def solution(relation):
answer = []
cal = [i for i in range(len(relation[0]))]
for i in range(1,len(cal)+1):
for c in combinations(cal,i):
if len(answer) == 0:
if dis(c,relation): answer.append(c)
else:
for li in answer:
if set(li).issubset(c): break
else:
if dis(c,relation): answer.append(c)
return len(answer)
다른 사람 본 후 코드 - 한번에 속성 묶어주기
from itertools import combinations
def dis(c,relation):
cals = [[j[i] for j in relation] for i in c]
set_ = [tuple(i[j] for j in c) for i in relation]
if len(set_) == len(set(set_)): return 1
else: return 0
def solution(relation):
answer = []
cal = [i for i in range(len(relation[0]))]
for i in range(1,len(cal)+1):
for c in combinations(cal,i):
if len(answer) == 0:
if dis(c,relation): answer.append(c)
else:
for li in answer:
if set(li).issubset(c): break
else:
if dis(c,relation): answer.append(c)
return len(answer)
22.10.04 코드
from itertools import combinations
def minimality(combo,answer):
for ans in answer:
# x.issubset(y) -> x가 y의 서브set인가?
if set(ans).issubset(combo): return 0
else: return 1
def uniqueness(relation, combo):
set_ = {tuple(rel[c] for c in combo) for rel in relation}
if len(relation) != len(set_): return 0
else: return 1
def solution(relation):
answer = []
cal = [i for i in range(len(relation[0]))]
for i in range(1,len(relation[0])+1):
for c in combinations(cal,i):
#희소성 고려
if minimality(c,answer) == 0: continue
#유일성 고려
if uniqueness(relation, c) == 1: answer.append(c)
return len(answer)