2017.07.21.금.11:50 [[[ 바로 잡음 및 바꿈 표, 새로 넣은 내용 ]]] 1. 바로 잡음 (틀린 내용을 바로 잡습니다.) * 다음과 같은 형식으로 고치기 전의 내용과 고친 뒤의 내용을 보입니다] 고치기 전 내용 --> 고친 뒤의 내용 1.1 중요한 내용 ----------------------------------------------------------- // 58 쪽, 아래에서 6 째 줄 달리 말하면, 주어진 수퍼키의 속성에서, 속성 하나라도 뺀다면 수퍼키가 될 수 없을 때, 주어진 수퍼키를 후보 키라고 부른다. ---> 달리 말하면, 주어진 수퍼키의 속성에서, 각 속성 하나를 뺀 모든 경우에 수퍼키가 될 수 없을 때, 주어진 수퍼키를 후보 키라고 부른다. 보기를 들어, {a1, a2, a3}가 수퍼키라고 하자. 여기서 a1을 뺀 {a2, a3} 가 수퍼키가 아니고, a2를 뺀 {a1, a3} 도 수퍼키가 아니고, a3을 뺀 {a1, a2} 도 수퍼키가 아니라면, 이 때 {a1, a2, a3}를 후보 키라고 한다. 만일 a1을 뺀 {a2, a3}가 수퍼키가 될 수 있다면 {a1, a1, a3}는 후보키가 아니며, 마찬가지로 만일 a1을 뺀 {a1, a3}가 수퍼키가 될 수 있다면 {a1, a1, a3}는 후보 키가 아니다. // 135 쪽 - 위에서 아홉째 줄: t3학생 --> t4학생 - 위에서 열네째 줄, 열여섯째 줄: t2. --> t2학생. - 위에서 열다섯째 줄, 열일곱째 줄: t4. --> t4학생. // 141 쪽, 아래 표 두개 바로 윗 줄: ... 학생의 학번을 보여라. ---> ... 학생의 학번과 이름을 보여라. // 141 쪽, 맨 아래 오른쪽 학생 표에서 과목번호 ---> 이름 // 142 쪽, 위에서 네째 줄: select t1수강.학번 ---> select t1수강.학번, t1학생.이름 // 143 쪽, 맨 아래 학생 표에서 과목번호 ---> 이름 // 152 쪽, 아래에서 7째 줄 R1 union R2 ---> (select * from R1) union (select * from R2) // 153 쪽, 아래에서 5-6 째 줄 "만일 겹치는 투플도 결과 테이블에 포함시키려면 intersect all 하면 된다" --> 뺀다. // 153 쪽, 맨 아래 줄 R1 intersect R2 ---> (select * from R1) intersect (select * from R2) // 155 쪽, 아래에서 6-7 째 줄 "만일 겹치는 투플도 결과 테이블에 포함시키려면 except all 하면 된다" --> 뺀다. // 156 쪽, 맨 윗 줄 R1 except R2 ---> (select * from R1) except (또는 minus) (select * from R2) // 156 쪽, 위에서 아홉째 줄 R2 except R1 ---> (select * from R2) except (또는 minus) (select * from R1) // 187 쪽, 위에서 네째 줄 R1 union R2 ---> (select * from R2) union (select * from R1) // 253 쪽, 맨 아래 보기에서 FD1: {과목 번호} ---> {과목 이름} FD2: {학번} ---> {학과 번호, 이름, 집전화} FD3: {학과 번호} ---> {학과 이름} --> FD1: {과목번호} ---> {과목이름} FD2: {학과번호} ---> {학과이름} FD3: {학번} ---> {학과번호, 이름, 집전화} // 254 쪽, 위의 보기에서 FD1: {과목 번호} ---> {과목 이름} FD2: {학번} ---> {학과 번호, 이름, 집전화} FD3: {학과 번호} ---> {학과 이름} FD4: {학번, 과목 번호} --> {성적 등급} --> FD1: {과목번호} ---> {과목이름} FD2: {학과번호} ---> {학과이름} FD3: {학번} ---> {학과번호, 이름, 집전화} FD4: {학번, 과목 번호} --> {성적 등급} 1.2 사소한 오타 등 -------------------------------------------------------- - 97 쪽, 위에서 3 째 줄 카티전 곱은 다른 테이블에 있는 ... ---> 카티전 곱은 여러 테이블에 (보통은 테이블 2 개에) 있는 ... - 115 쪽, 가운데 그림자 진 부분의 create table 명령에서 unique key (주번) ---> unique (주번) - 115 쪽, 아래에서 여섯째 줄 unique key 절 ---> unique 절 - 201 쪽, 가운데 그림자 진 부분의 create table 명령에서 unique key (주번) ---> unique (주번) - 201 쪽, 가운데 그림자 진 부분 위 둘째 줄, unique key 절 ---> unique 절 2. 바꿈 (틀린 내용은 아니지만, 더 잘 알 수 있도록 고치는 것입니다.) -------- (아직 없음) 3. 새로 넣은 부분 (책에 없는 내용을 보충한 것임) --------------------------- // 104 쪽, 3.5 바로 위에 다음 내용을 더 넣음 - natural join을 하는 이유 (목적) 보기를 들어 학생 표(학번, 이름)와 수강 표(학번, 과목_번호)가 있는데, (학번, 이름, 과목_번호)를 원하면, 표 하나에서 이 모든 정보를 가져올 수 없다. 학생 표에는 과목_번호가 없으며, 수강 표에는 이름이 없다. 이런 경우에 학생 표와 수강 표를 자연 조인하면 원하는 정보(학번, 이름, 과목_번호)를 모두 볼 수 있다. 그런데 학번 속성이 수강 표에서는 외래 키이고, 학생 표에서는 일차 키인데, 이처럼 어떤 속성(또는 속성의 집합)이 한 표에서는 외래 키, 또 다른 표에서는 일차 키인 때 이 두 표를 자연 조인하는 것이 자연 조인의 대부분을 차지한다. 이렇게 자연 조인 함으로써 외래 키인 수강 표(학번, 과목_번호)에 있는 정보에다, 학번이 일차 키인 학생 표에서 가져온 정보인 이름 속성을 한 표에 모을 수 있게 된다. 그러나 때로는 같은 표 두 개에 대하여 자연 조인할 수도 있는데, 이 때는 표 안에 있는 투플 두 개를 비교할 (견줄) 수 있게 된다. 뒤의 4.8에서 투플 변수를 배울 때, 이런 보기를 보게 된다. // 108 쪽, 맨 아래에 더 넣음 이 책에 나오는 SQL 명령은 일반적으로 거의 모든 DBMS의 SQL 처리기에서 잘 돌아간다. 특별히 DBMS에 따라 차이가 있는 SQL 명령은, 각 명령에 그런 사실은 적어두었다. 결론적으로 어떤 DBMS에서 SQL을 실습하더라도, 이 책을 읽는 데 아무런 문제가 없다. // 116 쪽, "테이틀에 투플 넣기" 바로 위에 넣음 위의 수강 표에서 "foreign key (학번)에서 알 수 있듯히 학번 속성은 외래 키이며, 또한 "references 학생"에서 알 수 있듯이 학생 표에서 학번 속성은 일차 키이다. 이런 경우, 수강 표의 외래 키 "학번" 속성 이름은 과목 표의 일차 키 속성 "학번"과 꼭 같아야 한다. create table 학생_표 ( 학번 varchar2(9), 이름 varchar2(20), primary key (학번)) // 122 쪽, 동그라미 1 아래에 넣음 그런데 많은 표에는 일차 키가 있는데, 이런 경우에는 DBMS에서 일차 키가 겹치는 것을 허용하지 않으므로 결과적으로 겹치는 투플은 생기지 않는다. 일차 키나 unique key 가 없을 때에 비로소 insert/update 명령의 결과로 겹치는 투플이 생길 수 있다. // 199 쪽, 아래에서 9 째 줄 위에 넣음 참고: 학번 9902101 을 학생 테이블에서 지울 때 생기는 문제도 생각해 볼 수 있지만, 위에서 본 일차 키 문제 때문에 학번을 바꿀 수 없기 때문에, 굳이 지울 때 생기는 문제는 따로 살펴보지 않았다. // 201 쪽, 위에서 11 째 줄 아래에 넣음 참고: 수강 표의 foreign key (학번)과 학생 표의 primary key (학번)에서 공통 속성인 학번의 속성 이름은 꼭 같아야 한다. 참고: 외래 키가 다른 스키마의 일차 키를 참조한다고 하였는데, 외래 키의 속성 전체(집합)와 다른 스키마의 일차 키 전체(집합)가 같아야 한다. 보기를 들어 아래와 같은 경우 foreign key는 다른 표의 일차 키 (학번, 주번)와 같지 않고, 다른 표의 일차 키의 일부에 지나지 않기 때문에 foreign key (학번)은 잘못된 것이다. create table t1 ... foreign key (학번) ... create table t2 ... primary key (학번, 주번) ... // 235 쪽, 9 째줄 아래 참고. 자주 일어나지는 않지만 다음과 같은 경우가 있을 수 있다. 물음. 아래의 R1과 R2에서 FD0: {학번} --> {학과 이름}을 확인하려면 R1 과 R2 를 자연 조인해야 하는지 아니면 자연 조인 하지 않고도 확인할 수 있는지 말하라. - R1 : {학과 번호, 학과 이름} FD1: {학과 번호} --> {학과 이름} - R2 : {학번, 학과 번호} FD2: {학번} --> {학과 번호} 풀이. 1) R1에 {학번, 학과 이름}이 없으므로 R1 만 확인하여서는 FD0 가 지켜지는지 않는지 확인할 수 없다. 2) R2에도 {학번, 학과 이름}이 없으므로 R2 만 확인하여서는 FD0 가 지켜지는지 않는지 확인할 수 없다. 3) 그러나 - R1 만 보고 FD1 가 지켜지는지 확인할 수 있고, - R2 만 보고 FD2 가 지켜지는지 확인할 수 있으므로, - FD1 과 FD2 에서 FD0 를 이끌어 낼 수 있다. (암스트롱의 규칙 A3. 옮겨가기 규칙에 의하여) - 따라서 R1과 R2 를 자연 조인 하지 않아도 R1, R2 에서 FD0 가 지켜지는지 않는지 확인할 수 있다. 4) 어떤 나누기가 종속을 유지하는지 않는지 확인할 때의 기준은 "어떤 함수적 종속이 지켜지는지 않는지 확인하기 위하여 자연 조인을 해야 되느냐? 하지 않아도 되느냐?" 이다. - 위의 보기에서 함수적 종속 FD0 이 지켜지는지 않는지 확인하기 위하여는 "R1 과 R2 를 자연 조인 하지 않아도 된다" 가 결론이다. // 267 쪽, 가운데 8.5 바로 위 BCNF와 3NF으로 나누는 절차의 다른 점: BCNF와 3NF으로 나누는 절차(algorithm)가 꽤 다른데도, 거의 모든 책에서 이 두 절차의 차이점을 제대로 풀이하지 않고 넘어가고 있다. 그 결과, 이 두 절차의 다른 점과 같은 점을 잘 알지 못하는 학생이 많다. 이제 두 절차의 다른 점과 같은 점을 찬찬히 살펴보겠는데, 확실하게 이해할 수 있도록 여러가지 각도에서 풀이하겠다. (1) BCNF/3NF 나누기할 때 다른 점 먼저 BCNF로 나누기에서는, BCNF 정의를 어기는 함수적 종속마다 스키마 한 개를 두 개의 조그만 스키마로 나눈다. 따라서 BCNF 정의를 어기지 않는 함수적 종속 때문에 스키마를 둘로 나누지는 않는다. 거기에 견주어 3NF 나누기에서는 3NF 정의를 어기는 함수적 종속이 하나만 있어도 3NF으로 나누는 절차에 들어가게 되는데, 3NF로 나눌 때 3NF 정의를 어기는 함수적 종속과 어기지 않는 함수적 종속을 구별하지 않고, 모든 함수적 종속에 있는 속성으로 이루어진 조그만 스키마를 한 개씩 따로 만든다. 그렇게 하는 이유는, 스키마 한 개만 보고도 함수적 종속이 지켜지는지 않는지 확인할 수 있게 하려면, 각 함수적 종속에 있는 모든 속성으로 이루어진 조그만 스키마를 따로 만들어야 하기 때문이다. (2) 나누기를 하려면 BCNF/3NF 정의를 어기는 함수적 종속을 모두 파악해야 하는지? (다른 점) 확인하는 뜻에서 한 가지 덧붙이면, BCNF 나누기에서는 BCNF 정의를 어기는 함수적 종속을 모두 파악해야 BCNF 나누기를 할 수 있지만, 3NF 나누기에서는 3NF 정의를 어기는 함수적 종속 한 개만 찾아내면, 나머지 함수적 종속이 3NF 정의를 어기는지 어기지 않는지 확인할 필요없이 바로 3NF 나누기로 들어가면 된다. (잘 이해가 되는지? 만일 이 말을 확실히 모르면 위에 있는 BCNF와 3NF 나누기의 차이를 제대로 이해하지 못했기 때문이므로 그 부분을 다시 읽어보기 바란다.) (3) 어떤 스키마가 BCNF/3NF에 있지 않다는 것을 알아내려면 (같은 점) 함수적 종속 하나라도 BCNF/3NF을 어긴다는 것을 알게 되면, 우리는 곧바로 그 스키마가 BCNF/3NF에 있지 않다고 결론내릴 수 있다. 이 점은 BCNF와 3NF에서 꼭 같다. (4) 어떤 스키마가 BCNF/3NF에 있다는 것을 확인하기 위하여는 (같은 점) 모든 함수적 종속이 BCNF/3NF 정의를 어기지 않는다는 것을 확인해야 비로소 우리는 그 스키마가 BCNF/3NF에 있다는 것을 알 수 있다. 이 점은 BCNF와 3NF에서 꼭 같다. 이제 BCNF 나누기와 3NF 나누기의 차이를 잘 알게 됐으리라고 본다. (아직도 잘 이해하지 못한 사람은 자기가 "대기 만성형"이라고 스스로 위로하면서, 위의 풀이를 다시 한 번 자세히 읽어보기 바란다. 읽고 또 읽으면 깨치지 못할 이유가 전혀 없다.) // 300 쪽, A.2.2 맨 마지막에 아래 내용을 더 넣는다 A.8 sqlldr 명령을 써서 자료를 표에 넣는 절차 (보기) 1) sqlplus 안에서 학생 표를 만든다. - SQL> prompt 때 SQL> @ldr1a <-- 실행시킨다 -- (file=ldr1a.sql 내용) drop table 학생 / create table 학생 ( 학번 varchar2(9), 이름 varchar2(20), 학점_수 int) / -- (끝) 2) unix prompt에서 sqlldr 명령을 써서 학생 표에 투플(자료)를 넣는다 % ldr1.go <-- 실행시킨다 -- (file=ldr1.go 내용) % sqlldr db000 control=ldr1.ctl -- (끝) -- (file=ldr1.ctl 내용) load data infile * into table 학생 fields terminated by ',' optionally enclosed by '"' (학번, 이름, 학점_수) begindata "11","홍 길동",3 "22","임 꺽정",4 "33","김 구",44 44, 홍 경래,999 -- (끝) 3) sqlplus 안에서 학생 표에 들어간 표를 찍어본다 - SQL> prompt 때 SQL> @ldr1b <-- 실행시킨다 -- (file=ldr1b.sql 내용) select * from 학생 / -- (끝) // 302 쪽, A.2.2 바로 위에 아래 내용을 더 넣는다 - 암호를 보이지 않게 하려면 다음과 같이 하면 된다: % mysql -ugimgs -p dbname // 306 쪽 A.3 바로 위에 아래 내용을 더 넣는다. - A.2.10 mysql> \T mp7.out (화면에 나오는 결과가 파일로도 간다) // 307 쪽 A.4 바로 위에 아래 내용을 더 넣는다. - 3.4 user password 바꾸기 . mysql에서 개인 계정으로 로그온 해서 . MySQL> set password = password('새_비밀번호'); 끝.