MySQL 기본

MySQL 기본

파이썬을 쓸때 주로 DBMS로 PostgreSQL을 사용하고있다. 관계형 데이터베이스 시스템들이 그렇게 큰 차이를 보이는 건 아니지만 mysql을 다루고 있는 책들이 워낙 많기도하고 데이터베이스를 공부하는 김에 mysql도 한번 정리해 본다.

설치

맥북을 이용하고 있기 때문에 Homebrew를 이용하여 설치했다

1
2
brew update
brew install mysql

서버 실행

서버를 실행해 주어야 한다. mysql이 설치된 곳으로 가서 아래와 같은 명령어를 입력한다

1
2
# /usr/local/bin
mysql.server start

서버 접속

brew를 통해 설치를 해 주었고 which 명령어를 통해 설치된 곳을 찾았다. 처음에는 기본 로그인 계정에 해당하는 아이디로 자동로그인을 시도하는데 비밀번호를 설정하지 않았기 때문에 실패하게 된다. 따라서 일단 실습을 진행하기 위해 root 계정으로 접속해보자.

1
mysql -u root

실습 준비

MySQL을 설치하면 기본적으로 다양한 샘플 데이터가 있다고한다. 하지만 brew를 통해서 설치해서 그런지 몰라도 아무런 샘플 데이터가 없었다. 실습을 준비하기 위해서 world 샘플 데이터를 받는 것부터 시작해보자. https://dev.mysql.com/doc/index-other.html에서 world 데이터를 받을 수 있다. 압축을 해제해고 적당한 곳에 저장한 후 데이터베이스에 목록에 추가해보자.

1
SOURCE /world.sql;

그리고 등록된 데이터 베이스를 살펴보자.

1
show databases;
1
2
3
4
5
6
7
8
9
10
11
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| world |
+--------------------+
5 rows in set (0.00 sec)

world 데이터베이스가 추가된 것을 확인할 수 있다.

등록된 데이터베이스 확인

1
2
# 복수형 databases임에 조심하자!!
show databases;

데이터베이스 선택과 테이블 확인

world 데이터베이스를 선택하고 테이블의 목록을 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> use world;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------+
| Tables_in_world |
+-----------------+
| city |
| country |
| countrylanguage |
+-----------------+
3 rows in set (0.00 sec)

테이블을 지정해서 데이터 출력

city / country / countrylanguage 세 가지 테이블 중에서 하나를 골라 모든 데이터를 출력해보자

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> SELECT * FROM city;
+------+------------------------------------+-------------+------------------------+------------+
/////////////////////////////////////////////////////////////////////////////////////////////////
| 4072 | Mutare | ZWE | Manicaland | 131367 |
| 4073 | Gweru | ZWE | Midlands | 128037 |
| 4074 | Gaza | PSE | Gaza | 353632 |
| 4075 | Khan Yunis | PSE | Khan Yunis | 123175 |
| 4076 | Hebron | PSE | Hebron | 119401 |
| 4077 | Jabaliya | PSE | North Gaza | 113901 |
| 4078 | Nablus | PSE | Nablus | 100231 |
| 4079 | Rafah | PSE | Rafah | 92020 |
+------+------------------------------------+-------------+------------------------+------------+
4079 rows in set (0.01 sec)

조건 지정출력1

WHERE 구문을 이용해 지정된 조건에만 충족하는 데이터들을 추려낼 수 있다. 아래의 예시코드는 한국의 도시 이름만 추려서 출력하고있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> select * from city where countrycode="KOR";
+------+------------+-------------+---------------+------------+
| 2388 | Sangju | KOR | Kyongsangbuk | 124116 |
| 2389 | Poryong | KOR | Chungchongnam | 122604 |
| 2390 | Kwang-yang | KOR | Chollanam | 122052 |
| 2391 | Miryang | KOR | Kyongsangnam | 121501 |
| 2392 | Hanam | KOR | Kyonggi | 115812 |
| 2393 | Kimje | KOR | Chollabuk | 115427 |
| 2394 | Yongchon | KOR | Kyongsangbuk | 113511 |
| 2395 | Sachon | KOR | Kyongsangnam | 113494 |
| 2396 | Uiwang | KOR | Kyonggi | 108788 |
| 2397 | Naju | KOR | Chollanam | 107831 |
| 2398 | Namwon | KOR | Chollabuk | 103544 |
| 2399 | Tonghae | KOR | Kang-won | 95472 |
| 2400 | Mun-gyong | KOR | Kyongsangbuk | 92239 |
+------+------------+-------------+---------------+------------+
70 rows in set (0.01 sec)

조건 지정출력2

이번에는 전라남도에 속한 도시만을 추려보자!

1
2
3
4
5
6
7
8
9
10
11
mysql> select * from city where district="chollanam";
+------+------------+-------------+-----------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------+-------------+-----------+------------+
| 2360 | Sunchon | KOR | Chollanam | 249263 |
| 2361 | Mokpo | KOR | Chollanam | 247452 |
| 2370 | Yosu | KOR | Chollanam | 183596 |
| 2390 | Kwang-yang | KOR | Chollanam | 122052 |
| 2397 | Naju | KOR | Chollanam | 107831 |
+------+------------+-------------+-----------+------------+
5 rows in set (0.01 sec)

불필요한 열 제거하기

지금까지는 테이블에 있는 모든 열을 출력했지만 원하는 열만 보기위해 지정하여 출력할 수 있다. 다음의 예시는 Name과 Population 열만 출력하고 있다.

1
2
3
4
5
6
7
8
9
10
11
mysql> select Name, Population from city where district="chollanam";
+------------+------------+
| Name | Population |
+------------+------------+
| Sunchon | 249263 |
| Mokpo | 247452 |
| Yosu | 183596 |
| Kwang-yang | 122052 |
| Naju | 107831 |
+------------+------------+
5 rows in set (0.01 sec)

다양한 조건 추가1

조건을 지정해 줄때 여러개도 가능하다. 전라남도에 속하면서 인구 수가 150000명이 넘는 도시를 출력했다.

1
2
3
4
5
6
7
8
9
mysql> select Name, Population from city where district="chollanam" and Population > 150000;
+---------+------------+
| Name | Population |
+---------+------------+
| Sunchon | 249263 |
| Mokpo | 247452 |
| Yosu | 183596 |
+---------+------------+
3 rows in set (0.00 sec)

정리

테이블을 보기 위해선 데이터베이스를 선택해야 한다. 1개의 데이터베이스에는 복수의 테이블이 저장되어 있기 때문이다.
데이터베이스의 목록을 보려면 show databases;
데이터베이스를 지정하려면 use ;
해당 데이터베이스의 테이블 목록을 보려면 show tables;
명령을 사용하면 된다.

주의
show 명령은 SQL의 명령어가 아니라 MySQL에서 제공하는 관리 명령이다

SELECT 문

SELECT 열 FROM 테이블명;
select 뒤에 column명을 from 뒤에 table명을 적어주면 된다. select *처럼 column에 (별표)를 적어주게 되면 테이블의 전체 열을 지정할 수 있고, 임의의 열을 콤마(,)로 구분해 복수로 지정하는 것도 가능하다. 또한 FROM의 테이블 명도 *데이터베이스.테이블**과 같이 명시적으로 지정하는 것도 가능하다.

WHERE 조건

원하는 column의 조건만을 충족하는 데이터들(row)만을 추리기 위해서는 WHERE를 이용해 조건을 지정해주면 된다.
SELECT 열명 FROM 테이블명 WHERE 조건;

검색결과 정렬

한국에 있는 도시들을 인구가 적은 순으로 나열(오름차순) 해보자. - 검색 결과의 정렬에는 ORDER BY를 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> select * from city where countrycode="KOR" order by population;
+------+------------+-------------+---------------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------+-------------+---------------+------------+
| 2400 | Mun-gyong | KOR | Kyongsangbuk | 92239 |
| 2399 | Tonghae | KOR | Kang-won | 95472 |
| 2398 | Namwon | KOR | Chollabuk | 103544 |
| 2397 | Naju | KOR | Chollanam | 107831 |
| 2396 | Uiwang | KOR | Kyonggi | 108788 |
| 2395 | Sachon | KOR | Kyongsangnam | 113494 |
| 2394 | Yongchon | KOR | Kyongsangbuk | 113511 |
| 2393 | Kimje | KOR | Chollabuk | 115427 |
| 2392 | Hanam | KOR | Kyonggi | 115812 |
| 2391 | Miryang | KOR | Kyongsangnam | 121501 |
| 2390 | Kwang-yang | KOR | Chollanam | 122052 |
+------+------------+-------------+---------------+------------+

테이블 집약

행수를 카운트하려면 아래와 같이 한다.

1
2
3
4
5
6
7
mysql> select count(*) from city where countrycode="KOR";
+----------+
| count(*) |
+----------+
| 70 |
+----------+
1 row in set (0.01 sec)

카운트 뿐만 아니라 최소(min) / 최대(max) / 합계(sum) / 평균(avg)을 구할 수 있다.

1
2
3
4
5
6
7
8
# 최소인구 / 최대인구 / 총 인구 / 평균 인구
mysql> select min(population), max(population), sum(population), avg(population) from city where countrycode="KOR";
+-----------------+-----------------+-----------------+-----------------+
| min(population) | max(population) | sum(population) | avg(population) |
+-----------------+-----------------+-----------------+-----------------+
| 92239 | 9981619 | 38999893 | 557141.3286 |
+-----------------+-----------------+-----------------+-----------------+
1 row in set (0.01 sec)

count처럼 행의 갯수를 세는 것과 sum / min 처럼 column의 집약도 가능하지만 문자열 집약도 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
mysql> select name from city where countrycode="KOR" and district="Chollabuk";
+----------+
| name |
+----------+
| Chonju |
| Iksan |
| Kunsan |
| Chong-up |
| Kimje |
| Namwon |
+----------+
6 rows in set (0.00 sec)

한 행으로 집약하려면 아래와 같이 한다.

1
2
3
4
5
6
7
mysql> select group_concat(name) from city where countrycode="KOR" and district="Chollabuk";
+-------------------------------------------+
| group_concat(name) |
+-------------------------------------------+
| Chonju,Iksan,Kunsan,Chong-up,Kimje,Namwon |
+-------------------------------------------+
1 row in set (0.00 sec)

group by

그룹별로 나눌 수도 있다. - group by 이용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ysql> select district, count(*) from city where countrycode="KOR" group by district;
+---------------+----------+
| district | count(*) |
+---------------+----------+
| Cheju | 1 |
| Chollabuk | 6 |
| Chollanam | 5 |
| Chungchongbuk | 3 |
| Chungchongnam | 6 |
| Inchon | 1 |
| Kang-won | 4 |
| Kwangju | 1 |
| Kyonggi | 18 |
| Kyongsangbuk | 10 |
| Kyongsangnam | 11 |
| Pusan | 1 |
| Seoul | 1 |
| Taegu | 1 |
| Taejon | 1 |
+---------------+----------+
15 rows in set (0.00 sec)

그룹지어서 결과를 보고자 할때 having 키워드를 이용해서 조건을 지정해 줄 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select district, count(*) from city where countrycode="KOR" group by district having count(*) = 1;
+----------+----------+
| district | count(*) |
+----------+----------+
| Cheju | 1 |
| Inchon | 1 |
| Kwangju | 1 |
| Pusan | 1 |
| Seoul | 1 |
| Taegu | 1 |
| Taejon | 1 |
+----------+----------+
7 rows in set (0.00 sec)

정리

검색결과 정렬

보통 SELECT 문을 실행하면 열과 행으로 구성된 2차원 표로 표시된다. 행의 순서를 정렬하기 위해 ORDER BY를 사용해서 할 수 있으며 기본 값은 오름차순이고 값을 DESC로 줌으로써 내림차순 정렬도 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> select * from city where countrycode="KOR" order by population desc;
+------+------------+-------------+---------------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------+-------------+---------------+------------+
| 2331 | Seoul | KOR | Seoul | 9981619 |
| 2332 | Pusan | KOR | Pusan | 3804522 |
| 2333 | Inchon | KOR | Inchon | 2559424 |
| 2334 | Taegu | KOR | Taegu | 2548568 |
| 2335 | Taejon | KOR | Taejon | 1425835 |
| 2336 | Kwangju | KOR | Kwangju | 1368341 |
| 2337 | Ulsan | KOR | Kyongsangnam | 1084891 |
| 2338 | Songnam | KOR | Kyonggi | 869094 |
| 2339 | Puchon | KOR | Kyonggi | 779412 |
| 2340 | Suwon | KOR | Kyonggi | 755550 |
| 2341 | Anyang | KOR | Kyonggi | 591106 |
| 2342 | Chonju | KOR | Chollabuk | 563153 |

정렬할 때에 주의할 점

order by로 정렬을 수행할 때 행의 순서를 확실히 같게 하려면 행의 정렬키의 값들이 각각 고유해야 한다. 다시 말하면, 정렬키가 같은 값의 행이 복수 개 존재한다면 그 행들의 순서는 일정하지 않을 수 있다는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from city where countrycode="KOR" order by district;
+------+------------+-------------+---------------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------+-------------+---------------+------------+
| 2358 | Cheju | KOR | Cheju | 258511 |
| 2398 | Namwon | KOR | Chollabuk | 103544 |
| 2380 | Chong-up | KOR | Chollabuk | 139111 |
| 2342 | Chonju | KOR | Chollabuk | 563153 |
| 2397 | Naju | KOR | Chollanam | 107831 |
| 2370 | Yosu | KOR | Chollanam | 183596 |
| 2390 | Kwang-yang | KOR | Chollanam | 122052 |
| 2361 | Mokpo | KOR | Chollanam | 247452 |
| 2360 | Sunchon | KOR | Chollanam | 249263 |

위의 결과를 보면 district를 정렬키로 정렬했는데 전라남도는 5개의 행이 있는데 그 다섯 개 행 내의 순서는 일정하지 않게 된다.
일정한 순서로 정렬하기 위해서 name도 정렬키로 추가해주는 것이 좋다.

1
mysql> select * from city where countrycode="KOR" order by district, name;

테이블 요약

SQL에서 데이터에 대해 어떠한 ㅗ짝이나 계산을 수행하려면 함수를 사용한다. 함수는 크게 두 가지가 있는데

  1. 복수 행(or 행의 값)에 대해 집계
  2. 단일 행의 값에 대해 조작이나 계산
    을 수행하는 역할을 한다.

예를 들면 위에서 한번 살펴본 count 함수이다. 이런 집계용 함수를 집약함수(집계함수)라고 부른다.

  • COUNT : 테이블의 행 수를 계산
  • SUM : 테이블의 수치 데이터를 합계
  • AVG : 테이블의 수치 데이터 평균을 구함
  • MAX : 테이블의 임의열 데이터 중 최대값을 구함
  • MIN : 테이블의 임의열 데이터 중 최소값을 구함

기본적으로 집계함수는 NULL을 제외하고 계산한다. 하지만 COUNT함수는 예외인데 NULL을 포함한 조건으로 주어진 모든 행을 집계한다.

문자열 집약

문자열을 집약하는 함수로는 GROUP_CONCAT가 있다. 표준 SQL에는 없지만 MySQL에서 제공해주는 함수이다. SUM과 같은 함수는 수치에 대해서 집계를 해주지만 GROUP_CONCAT 함수는 문자열에 대한 집계를 문자열의 결합으로 수행한다.

중복제거

DISTINCT 키워드를 통해 중복을 제거할 수 있다. 또한 집약함수로도 이용할 수 있다.

1
2
mysql> select group_concat(district) from city where countrycode="KOR";
| Seoul,Pusan,Inchon,Taegu,Taejon,Kwangju,Kyongsangnam,Kyonggi,Kyonggi,Kyonggi,Kyonggi,Chollabuk,Chungchongbuk,Kyonggi,Kyonggi,Kyongsangbuk,Kyongsangnam,Kyongsangnam,Kyonggi,Chungchongnam,Kyongsangnam,Chollabuk,Kyonggi,Kyongsangbuk,Kyonggi,Kyongsangbuk,Chollabuk,Cheju,Kyongsangnam,Chollanam,Chollanam,Kyonggi,Kang-won,Kyonggi,Kang-won,Kyonggi,Kang-won,Chungchongbuk,Kyongsangbuk,Chollanam,Kyongsangbuk,Kyonggi,Kyongsangnam,Kyonggi,Chungchongnam,Kyongsangnam,Kyongsangbuk,Chungchongnam,Kyonggi,Chollabuk,Chungchongbuk,Chungchongnam,Kyonggi,Kyongsangnam,Chungchongnam,Kyongsangbuk,Kyongsangnam,Kyongsangbuk,Chungchongnam,Chollanam,Kyongsangnam,Kyonggi,Chollabuk,Kyongsangbuk,Kyongsangnam,Kyonggi,Chollanam,Chollabuk,Kang-won,Kyongsangbuk |

위 와 같이 단순히 행정구역을 group_concat하게 되면 값이 여러번 나오게된다. 이때에 distinct를 추가하게 되면 중복이 없어지고 각 행정구역은 1회만 나오게 된다.

1
2
3
4
5
6
7
mysql> select group_concat(distinct district) from city where countrycode="KOR";
+------------------------------------------------------------------------------------------------------------------------------------------+
| group_concat(distinct district) |
+------------------------------------------------------------------------------------------------------------------------------------------+
| Seoul,Pusan,Inchon,Taegu,Taejon,Kwangju,Kyongsangnam,Kyonggi,Chollabuk,Chungchongbuk,Kyongsangbuk,Chungchongnam,Cheju,Chollanam,Kang-won |
+------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

그룹핑(group_by)

지금까지 한 집약함수와는 다르게 대상이 되는 데이터를 몇 개의 그룹으로 나누어서 집약하는 것도 가능하다. GROUP_BY를 이용하여 그룹을 나눌 때는 키가 되는 열을 지정해 주어야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mysql> select count(*) from city where countrycode="KOR";
+----------+
| count(*) |
+----------+
| 70 |
+----------+
1 row in set (0.00 sec)


mysql> select district, count(*) from city where countrycode="KOR" group by district;
+---------------+----------+
| district | count(*) |
+---------------+----------+
| Cheju | 1 |
| Chollabuk | 6 |
| Chollanam | 5 |
| Chungchongbuk | 3 |
| Chungchongnam | 6 |
| Inchon | 1 |
| Kang-won | 4 |
| Kwangju | 1 |
| Kyonggi | 18 |
| Kyongsangbuk | 10 |
| Kyongsangnam | 11 |
| Pusan | 1 |
| Seoul | 1 |
| Taegu | 1 |
| Taejon | 1 |
+---------------+----------+
15 rows in set (0.00 sec)

그룹으로 나눈 후에 집약하기 위해서 조건을 추가해 줄 수 있다. 이전에 조건을 추가하기 위해서 where 구문을 사용한 적이 있는데 count 같은 집약 함수를 작성할 수 있는 경우는 SELECT와 ORDER BY 그리고 HAVING 밖에 없다. 따라서 집약한 결과에 조건을 지정하기 위해서는 HAVING 구문을 사용해야만 한다.

1
2
3
4
5
6
7
8
mysql> select district, count(*) from city where countrycode="KOR" group by district having count(*) = 6;
+---------------+----------+
| district | count(*) |
+---------------+----------+
| Chollabuk | 6 |
| Chungchongnam | 6 |
+---------------+----------+
2 rows in set (0.00 sec)

[참고]
https://dev.mysql.com/doc/index-other.html
https://dev.mysql.com/doc/world-setup/en/world-setup-installation.html
https://unagi44.wordpress.com/2015/09/16/mac-os-x%EC%97%90%EC%84%9C-mysql-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89/
http://aspdotnet.tistory.com/1848

Share

TCP/IP 4계층 - 인터넷 계층

인터넷 계층

IP 주소

인터넷 계층의 역할은 송신지 컴퓨터의 데이터를 수신지 컴퓨터까지 전달하는 것이다. 수신지 컴퓨터를 찾아내기 위해 식별할 수 있는 고유한 정보가 필요하고 이때에 사용되는 식별자가 바로 IP 주소이다. 흔히 IP 주소를 우편번호로 비유하곤 하는데, 자세히 들여다보면 중요한 차이가 존재한다. 우편번호는 지역정보를 포함하고 있는 것과 달리 IP 주소는 지리적인 위치와는 상관없이 네트워크 단위로 할당된다. 따라서 IP 주소를 통해 그 컴퓨터가 어느 위치에 존재하는 지 알기 힘들며 어느 네트워크에 속해있는 지와 소속된 네트워크의 규모를 짐작할 수 있을 뿐이다.

라우터

IP 주소는 지리적인 위치 정보를 포함하고 있지 않기 때문에 수신자를 찾기 위해서는 다른 방법을 이용해야 한다. 라우터(router)라는 네트워크 장비는 서로 다른 네트워크 간의 연결 정보를 관리한다. IP 주소를 보면 소속된 네트워크가 어디인지 알 수 있는데, 해당 네트워크에 연결된 라우터를 추적하다 보면 그 장비가 최종적으로는 목표로 한 수신지 컴퓨터를 찾게되고 송신지에서 수신지까지 연결되는 통신 경로를 만들 수 있게 된다. 이와 같은 과정을 라우팅(routing) 이라고 한다.

공인 IP / 사설 IP

급속한 인터넷의 보급으로 사용 가능한 IP 주소가 점점 줄어들고있다. 이와 같은 현상을 피하기위한 방안으로 사설 IP / 공인 IP를 구분하는 기법을 사용한다. 또한 근본적인 방법으로 고갈되어져 가는 IPv4 주소체계를 IPv6로 확장하고 있다.

  • 공인 IP
    Public IP라고 불린다. 인터넷에서 사용가능한 IP 주소를 말하며, 외부에서도 접근이 가능한 주소를 의미한다.

  • 사설 IP
    Private IP라고 불린다. 사무실이나 가정 내에서만 사용 가능한 IP이며, 외부에서 접근할 수 없는 주소이다.

IPv4 와 IPv6

인터넷 계층에서 사용되는 프로토콜이다. IP 주소를 결정할 때 사용하는 비트의 길이가 다르다. IP 주소는 유통기한을 가지고 있는데, 패킷이 제대로 전달되지 않는 경우 네트워크 안을 계속해서 떠도는 걸 방지하기 위함이다. 제대로 전달되지 않은채 네트워크 안을 떠돌게되는 패킷이 많아지면 자연스레 네트워크는 복잡해져 다른 패킷들에게도 영향을 미치게 되는데 이러한 부작용을 방지하기 위해 IPv4 헤더에는 생존기간(TTL - Time To Live) 정보가 담겨져있다. TTL이 0인 패킷이 발견된다면 그 패킷을 소멸시키도록 규정하고 있다.

  1. IPv4
    32비트 주소 체계이다. 32비트 문자열은 사람이 알아보기 어렵기 때문에 8비트씩 4개 단위로 끊은 후에 10진수로 변환하여 표현한다.

  2. IPv6
    128비트 주소 체계이다. 급격한 인터넷의 성장으로 IPv4의 주소가 고갈되어가자 피해를 방지하기 위해 만들어졌다.

    인터넷 계층에서 사용되는 장비에만 IP 주소가 할당된다.

한 번에 전송할 수 있는 데이터의 크기를 **MTU(Maximum Transmission Unit)라고 한다. 통신 상태에 따라 달라지게 되는데, 예를 들어 경로 상태가 좋지 않으면 값이 줄어들게 되고 라우터는 이 MTU 값에 따라 패킷을 분할해서 수신지로 전송하게 된다. 라우터가 데이터를 송신하기 전에 통신 경로 전체의 MTU를 살펴보고 처음부터 MTU보다 작은 크기의 패킷을 전송하게 된다. 수신지의 컴퓨터에서는 도착한 분할된 패킷들을 복원하여 수신한다!

네트워크 부와 호스트 부

IP 주소는 네트워크 부와 호스트 부로 나누어 진다. 라우터는 IP 주소의 네트워크 부를 보고 데이터를 전송할 목적지가 같은 네트워크에 있는지 다른네트워크에 있는지 판단한다.

어드레스 클래스

하나의 IP 주소에서 어디까지가 네트워크 부이고 호스트 부인지 표현하기 위해 어드레스 클래스를 이용한다. 총 네 가지의 어드레스 클래스가 있다.

  • 클래스 A
    • 네트워크 부 : 8비트 - 126개 네트워크
    • 호스트 부 : 24비트 - 약 1677만개 호스트
  • 클래스 B
    • 네트워크 부 : 16비트 - 약 1만 6천개 네트워크
    • 호스트 부 : 16비트 - 약 6만 5천개 호스트
  • 클래스 C
    • 네트워크 부 : 24비트 - 약 209만개 네트워크
    • 호스트부 : 8비트 - 254개 호스트
  • 클래스 D (특수 클래스) : 멀티캐스트 그룹
    • 네트워크 부 : 32비트

클래스 A를 보면 한 개의 네트워크당 1677만개의 호스트를 할당할 수 있는데, 실제로 단일 네트워크에 이렇게 많은 호스트를 필요로 하는 경우는 없다. 이런 경우 호스트 낭비가 심하게 되는데 효율적으로 주소를 할당하고자 나온 방법이 서브넷 마스크이다.

서브넷 마스크

어드레스 클래스의 경우 네트워크 부의 길이가 미리 정해져있다. 어드레스 클래스와 다르게 네트워크 부의 길이를 가변적으로 사용하기 위해 서브넷 마스크를 사용하며, 비트 단위로 유연하게 늘려서 쓰는 것이 가능해진다.

네트워크 부를 1비트 단위로 변경할 수 있다!!
IP 주소를 할당하는 방법은 IPv4를 기준으로 전체 32비트 중 네트워크 부를 제외한 호스트 부분을 자유롭게 할당하여 사용하는 것이다.

Share

TCP/IP 4계층 - 트랜스포트 계층

트랜스포트 계층

컴퓨터 안까지 들어온 데이터를 각 애플리케이션까지 전달하는 것이 트랜스포트 계층의 역할이다. 여러 컴퓨터로부터 받은 데이터들은 트랜스포트 계층에서 포트번호에 의해 분류되고 각 포트번호에 맞는 애플리케이션으로 전달된다.

트랜스포트 계층 프로토콜

두 가지의 대표 프로토콜이 있다.

  1. TCP

    • 웹이나 이메일같이 데이터가 정확하게 전달되어야 하는 통신에 사용된다.
    • Transmission Control Protocol
    • 수신지의 통신 상태를 확인하고 제대로 전송이 안됐을 경우 재전송하는 기능도 한다.
    • 높은 신뢰성 - 패킷 전송여부 확인
  2. UDP

    • VoIP나 동영상 스트리밍처럼 전송 속도가 중요한 통신에 사용된다.
    • User Datagram Protocol
    • 낮은 신뢰성 - 패킷 전송여부 미확인

역할

  1. 애플리케이션에 데이터를 전달한다.
    인터넷 계층과의 차이점을 알아두어야 할 것 같다. 트랜스포트 계층은 컴퓨터가 받은 데이터를 애플리케이션에 전달하는 역할을 가지며, 인터넷 계층은 데이터를 수신지 컴퓨터까지 전달하는 것이다.

  2. 포트번호로 애플리케이션을 구분한다.
    인터넷 계층을 통해 들어온 데이터를 애플리케이션에 전달해야 하는데 이때에 포트번호를 이용해서 각 애플리케이션을 구분한다. 인터넷 계층에서 프로토콜 번호가 6번이면 TCP로, 17번이면 UDP를 통해 트랜스포트 계층으로 전달되고 각 애플리케이션의 포트번호를 가지고 어떠한 애플리케이션으로 데이터를 전달할지 구분한다.

포트번호

  • 포트 번호는 컴퓨터 내부의 수신지를 표현한다.
    인터넷 계층이 전달한 여러 종류의 패킷이 트랜스포트 계층으로 전될되는데 해당하는 어플리케이션에 다시 전달하기 위해서 포트번호를 사용한다.

    ip_addr/post-no.

  • 포트 번호의 범위
    포트 번호는 0 ~ 65535번 까지 사용할 수 있으며 세 종류로 나누기도 한다.

    1. well-known ports : 서버 프로그램이 수신 대기할때 사용하는 포트번호
    2. registered ports : 벤더가 할당받아 사용하는 포트번호
    3. dynamic ports : 클라이언트 프로그램이 동적으로 할당받아 사용하는 포트번호. 때문에 미리 알수 없는 특징이 있다.

클라이언트 - 서버 접속 과정

클라이언트 - 서버가 서로 통신하는 과정은 다음과 같다.

  1. 클라이언트가 사용할 포트를 먼저 정한다

    • 이때에 사용되는 포트구분은 dynamic 포트이다
  2. 서버의 포트에 접속한다.

    • HTTP의 경우 80번 포트로 대기중인데 클라이언트가 동적으로 할당받은 포트번호를 가지고 서버에 접속을 요청하게 된다.
  3. 접속 완료

    • 웹 서버가 접속을 허용하면 통신 가능한 상태가 되고 통신이 종료되면 클라이언트는 할당 받은 포트를 반납한다.

또한 서버는 IP주소와 포트 번호로 요청하는 상대방을 식별한다. 서버는 수신 대기를 위해 고정된 포트 번호를 사용하지만, 접속을 요청한 클라이언트들은 각기 다른 포트번호를 사용한다. 이때에 서버는 서로 다른 클라이언트들을 구분하기 위해 IP주소와 포트번호를 사용하여 혼선없이 통신한다.

TCP(Transmission Control Protocol)

데이터 전송에 신뢰성을 더하기 위해 데이터를 세그먼트(segment) 단위로 분할하고, 전송 속도를 조정하며, 데이터가 제대로 전달되지 않았을 경우 재전송을 한다.

커넥션을 맺는 과정으로 3단계가 있다. 3방향 핸드셰이크(3-way handshake)라고 부르며, 커넥션이 맺어지면 데이터를 전송할 수 있는 상태가 되고, 데이터 전송이 끝나면 커넥션을 끊는다.(SYN / ACK / FIN)

UDP(User Datagram Protocol)

통신 과정에서 데이터의 손실이 발생할 수 있는데, VoIP와 같은 음성 서비스나 동영상 스트리밍 서비스는 일부 데이터가 누락되거나 왜곡되더라도 큰 문제가 없기 때문에 UDP를 주로 사용한다.

Share