Search

5~6장 정리 (커넥션, SQL)

질문

nosql에 저장하기 좋은 데이터 형식과 rdb에 저장하기 좋은 형태는 어떤 것이 있을까요
MVCC에 대해서

5장

커넥션(Connection)
로그인을 통해 프롬프트가 표시된 것 사용자와 MySQL이 접속된 것 Connection
커넥션이 유지되는 한 사용자는 데이터베이스와 무언가를 주고받을 수 있음
로그인시 나타나는 메세지 중 아래의 문구는 커넥션이 성립되었음을 표시
Your MySQL connection id is 8
SQL
복사
connection id : MySQL과 사용자간의 커넥션에 붙인 번호
MySQL은 동시에 여러 커넥션을 유지하는 것이 가능
즉, 동시에 복수의 사용자와 연결 가능
어느 사용자와의 커넥션인지 번호로 관리
세션(Session)
커넥션의 시작과 종료 사이에 DBMS와 다양한 교환을 진행하는데, 그 교환의 시작과 종료까지의 단위가 세션(Session)
기본적으로 커넥션과 섹션은 1:1 대응되어 커넥션 성립 시 암묵적으로 세션이 시작되고, 세션을 끊으면 커넥션도 끊어지는 경우가 많으므로 세션과 커넥션을 잘 구분하지 않음
커넥션 상태 확인
mysql> show status like 'Threads_connected';
SQL
복사
Thread_connected의 값 = 사용자의 수
로그오프
커넥션 끊기

관계형 데이터베이스의 계층

인스턴스 > 데이터베이스 > 스키마 > 오브젝트(테이블, 인덱스, 저장 프로시저 등)
트리 구조
스키마(Schema)
스키마를 통해 테이블을 용도별로 나누거나 권한 관리 수행 가능
스키마 아래에 여러 테이블 존재 가능
오브젝트(Object)
최하위 계층
테이블(Table), 인덱스(Index), 저장 프로시저(Stored Procedure) 등
DBMS별 계층 구조
4계층 구조
PostgreSQL, SQL Server, SB2
3계층 구조 : 스키마와 데이터베이스의 한 계층을 생략
MySQL: 데이터베이스와 스키마를 동일한 것으로 간주 (동의어)
Oracle: 4계층 구조로 되어있긴 하지만 인스턴스 아래에 데이터베이스를 한 개만 만들 수 있어 실질적으로 3계층 구조
ANSI 표준으로 정해진 것은 4계층 구조
개발사의 의향에 따라 바뀔 수 있음

6장

DISTINCT
→특정 칼럼을 unique하게 정규화를 하려면 칼럼을 concat..?

SELECT 문을 응용해보자

아래와 같이 GROUP BY 구, 그리고 HAVING 구에 SELECT 구에서 사용하는 별칭(Alias)을 사용하면 SQL 문은 원하는 대로 작동할까? 우리는 SQL 문의 작동 순서에 있어 GROUP BY 구 및 HAVING 구가 SELECT 구에 우선이 된다고 알고 있기 때문에 작동이 안 될 것으로 판단할 수 있다.
SELECT district AS district_name, COUNT(ID) AS number_of_cities FROM city WHERE countrycode = 'KOR'GROUP BY district_name HAVING number_of_cities = 6;
Plain Text
복사
그러나 MySQL에서 실제로 쿼리를 실행해보면 아래와 같이 정상적으로 작동하는 걸 확인할 수 있다. 이는 DBMS 내부에서 처리해주는 부분으로 B.3.4.4 Problems with Column Aliases 문서를 확인해보면 GROUP BYORDER BYHAVING 구에서는 별칭을 사용할 수 있으며, WHERE 구에서는 별칭을 사용할 수 없다고 적혀 있다.
+---------------+------------------+ | district_name | number_of_cities | +---------------+------------------+ | Chollabuk | 6 | | Chungchongnam | 6 | +---------------+------------------+
Plain Text
복사
별칭을 사용할 때도 식별자(Identifier)를 사용해야 하며 단순히 문자열을 의미하는 따옴표('')를 사용할 경우, 문자열 리터럴(String Literal)로 참조되어 원하는 결과를 얻을 수 없다. 실제로 아래 쿼리를 실행하면 앞서 실행된 결과와 다른 결괏값을 반환한다.
SELECT district AS district_name, COUNT(ID) AS 'number_of_cities' FROM city WHERE countrycode = 'KOR'GROUP BY district_name HAVING 'number_of_cities' = 6;
Plain Text
복사
문자열 리터럴 'number_of_cities' 값 자체가 숫자 6과 다르기 때문에 거짓(False)을 의미하며, 결국 HAVING 구에 MySQL에서 거짓 불리언(Boolean) 대수 값을 의미하는 0이 전달 된다.
Empty set, 1 warning (0.01 sec)
Plain Text
복사
이때 SHOW WARNINGS 명령어를 실행하여 반환된 경고(Warning)를 살펴보면 아래와 같이 조건문, 다시 말해 HAVING 구에 비교할 수 없는 데이터가 존재할 때 반환하는 경고가 작성되어 있는 것을 확인할 수 있다.

View

View → CREATE VIEW 뷰 명 AS SELECT 문;
테이블 대신에 뷰를 사용하는 이점은 다음과 같음
1.
복잡한 SELECT 문을 일일이 매번 기술할 필요 X
2.
필요한 열과 행만 사용자에게 보여줄 수 있다. 갱신 시에도 뷰 정의에 따른 갱신으로 한정 가능
3.
기억 장치의 용량 사용 없는, 즉 데이터 저장 없이 실현 가능. 뷰를 제거해도 참조하는 테이블은 영향 받지 않음
뷰로의 입력, 갱신의 제한
어떤 행 대응하는지, 어떤 값을 넣으면 좋을지 모르는 경우에는 갱신 불가
group by로 집약한 수치, distinct로 얻은 값 갱신 → 테이블의 어느 행의 수치를 갱신하는 것이 좋은지 판단 불가
2가지 이상의 테이블 조합 및 작성한 뷰 갱신 시, 어느 테이블 갱신하면 좋을지 모름
뷰에서 원래 테이블의 일부 열만 선택되었다면 데이터를 삽입하려고 해도 선택된 열 이외에 열에 기본값도 없고 NULL도 허용되지 않는 상황에서는 해당 열에 넣을 수 있는 값이 없어서 실질적으로 뷰로의 삽입이 불가

DBMS 내의 NULL

null은 불명, 적용 불가를 나타냄
DBMS 내에서는 NULL의 사용을 그다지 권장 X
2가지 이유
1.
인간의 직감에 반하는 3개의 논리 값(true, false, null로 인한 unknown)
IS NULL 이 아닌 =NULL 로 하면 unknown 발생
2.
사칙연산 또는 SQL 함수의 인수에 null이 포함되면 null의 전파 발생
null은 비교 연산이 불가
일부 DBMS에서는 NULL을 포함한 비교 연산 구현됨
MySQL : <=>
A <=> B : 어느 쪽에 NULL이 포함되어 있어도 올바르게 비교 가능
SQL 표준
IS NOT DISTINCT FROM이 정의
null이 섞여 비교 수행