나는 이렇게 학습한다/DB

생활코딩 #테이블 분리하기, JOIN

daco2020 2021. 8. 14. 22:45
반응형

 오늘 배운 것 

 

테이블 분리하기

앞선 글에 적은 것처럼 테이블 분리는 데이터를 좀 더 효율적으로 관리하기 위함. 

아래는 실습 코드

MariaDB [(none)]> use daco;
Database changed

MariaDB [daco]> SHOW TABLES;
+----------------+
| Tables_in_daco |
+----------------+
| topic          |
+----------------+
1 row in set (0.008 sec)

MariaDB [daco]> RENAME TABLE topic TO topic_backup;
Query OK, 0 rows affected (0.041 sec)

# 테이블 이름 변경 방법 -> 리네임 테이블 (이름) 투 (새이름);

MariaDB [daco]> SELECT * FROM topic_backup;
+----+------------+----------------------------+---------------------+-----------+-----------+
| id | title      | description                | created             | author    | profile   |
+----+------------+----------------------------+---------------------+-----------+-----------+
|  1 | MySQL      | MySQL is my first database | 2021-08-09 21:07:51 | daco      | developer |
|  2 | ORACLE 2   | ORACLE is database         | 2021-08-09 21:13:02 | dacoZZING | developer |
|  4 | MongoDB    | MongoDB is database        | 2021-08-09 21:14:05 | daco      | developer |
|  5 | SQL Server | SQL Server is database     | 2021-08-09 21:14:57 | daco      | developer |
|  6 | MongoDB    | MongoDB is database        | 2021-08-11 21:36:16 | daco      | developer |
+----+------------+----------------------------+---------------------+-----------+-----------+
5 rows in set (0.008 sec)

# 일단 기존 topic 테이블은 백업해 두고 실습용 테이블 생성


MariaDB [daco]> CREATE TABLE topic(
    -> id INT(11) NOT NULL AUTO_INCREMENT,
    -> titile VARCHAR(30) NOT NULL,
    -> description TEXT NULL,
    -> created DATETIME NOT NULL,
    -> author_id INT(11) NULL,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.025 sec)

MariaDB [daco]> SHOW topic;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'topic' at line 1
MariaDB [daco]> SHOW tables;
+----------------+
| Tables_in_daco |
+----------------+
| topic          |
| topic_backup   |
+----------------+
2 rows in set (0.000 sec)

#잘 만들어졌는지 확인


MariaDB [daco]> DESC topic;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| titile      | varchar(30) | NO   |     | NULL    |                |
| description | text        | YES  |     | NULL    |                |
| created     | datetime    | NO   |     | NULL    |                |
| author_id   | int(11)     | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
5 rows in set (0.011 sec)

#DESC 는 설명을 뜻함. 즉, 테이블이 어떻게 설정되어있는 목록화 하여 보여주는 명령어


MariaDB [daco]> CREATE TABLE author (
    -> id INT(11) NOT NULL AUTO_INCREMENT,
    -> name VARCHAR(20) NOT NULL,
    -> profile VARCHAR(200) DEFAULT NULL,
    -> PRIMARY KEY (id)
    -> );
Query OK, 0 rows affected (0.017 sec)

#'author' 테이블도 만들어 주고


MariaDB [daco]> DESC author;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| name    | varchar(20)  | NO   |     | NULL    |                |
| profile | varchar(200) | YES  |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+
3 rows in set (0.009 sec)

MariaDB [daco]> INSERT INTO author (id, name, profile) VALUES(1, 'daco', 'developer');
Query OK, 1 row affected (0.002 sec)

# 'author' 테이블에 내용 집어넣기


MariaDB [daco]> SELECT * FROM author;
+----+------+-----------+
| id | name | profile   |
+----+------+-----------+
|  1 | daco | developer |
+----+------+-----------+
1 row in set (0.000 sec)

# 잘 들어갔는지 확인!



MariaDB [daco]> INSERT INTO topic(id, title, description, created, author_id) VALUES(1, 'MySQL', 'MySQL is...', '2018-1-1 12:10:11', 1);
ERROR 1054 (42S22): Unknown column 'title' in 'field list'

# topic 테이블에 데이터를 넣으려는데 오류가 남. title 이라는 컬럼이 없음..!?
# 알고 보니 테이블 만들 때 오타남. 그래서 컬럼명 수정할 수 있는 방법을 구글링함

MariaDB [daco]> ALTER TABLE topic CHANGE titile title VARCHAR(30) NOT NULL;
Query OK, 0 rows affected (0.013 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 컬럼 수정 방법은 [ ALTER TABLE 테이블명 CHANGE 기존컬럼명 변경할컬럼평 컬럼타입; ]



MariaDB [daco]> SHOW topic;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'topic' at line 1

# 이 오류는 SELECT로 테이블 데이터를 가져와야 하는데 
# SHOW 로 보여달라고 해서 나타나는 오류. (SHOW는 테이블 목록을 가져옴)


MariaDB [daco]> SELECT * FROM topic;
Empty set (0.000 sec)

# 이건 오류는 아니고 비어있다는 메시지


MariaDB [daco]> DESC topic;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| title       | varchar(30) | NO   |     | NULL    |                |
| description | text        | YES  |     | NULL    |                |
| created     | datetime    | NO   |     | NULL    |                |
| author_id   | int(11)     | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
5 rows in set (0.006 sec)

MariaDB [daco]> INSERT INTO topic(id, title, description, created, author_id) VALUES(1, 'MySQL', 'MySQL is...', '2018-1-1 12:10:11', 1);
Query OK, 1 row affected (0.002 sec)

MariaDB [daco]> INSERT INTO topic(id, title, description, created, author_id) VALUES(1, 'Oracle', 'Oracle is...', '2018-1-3 13:10:11', 1);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

# 이 에러는 id 값이 중복이 안되는데 중복되어서 뜨는 오류. 그래서 1을 2로 바꿔줌



MariaDB [daco]> INSERT INTO topic(id, title, description, created, author_id) VALUES(2, 'Oracle', 'Oracle is...', '2018-1-3 13:10:11', 1);
Query OK, 1 row affected (0.002 sec)

MariaDB [daco]> INSERT INTO author (id, name, profile) VALUES(2, 'ted', 'data administrator');
Query OK, 1 row affected (0.001 sec)

MariaDB [daco]> INSERT INTO topic(id, title, description, created, author_id) VALUES(3, 'SQL server', 'SQL is...', '2018-1-31 10:10:11', 2);
Query OK, 1 row affected (0.002 sec)

MariaDB [daco]> INSERT INTO author (id, name, profile) VALUES(3, 'jin', 'data scientist');
Query OK, 1 row affected (0.002 sec)

MariaDB [daco]> INSERT INTO topic(id, title, description, created, author_id) VALUES(4, 'Postgre SQL', 'PostgreSQL is...', '2018-1-16 5:10:11', 3);
Query OK, 1 row affected (0.002 sec)

MariaDB [daco]> INSERT INTO topic(id, title, description, created, author_id) VALUES(5, 'MongoDB', 'MongoDB is...', '2020-3-16 16:12:09', 1);
Query OK, 1 row affected (0.002 sec)

# 테이블 별로 데이터 다 넣고 


MariaDB [daco]> SELECT * FROM topic;
+----+-------------+------------------+---------------------+-----------+
| id | title       | description      | created             | author_id |
+----+-------------+------------------+---------------------+-----------+
|  1 | MySQL       | MySQL is...      | 2018-01-01 12:10:11 |         1 |
|  2 | Oracle      | Oracle is...     | 2018-01-03 13:10:11 |         1 |
|  3 | SQL server  | SQL is...        | 2018-01-31 10:10:11 |         2 |
|  4 | Postgre SQL | PostgreSQL is... | 2018-01-16 05:10:11 |         3 |
|  5 | MongoDB     | MongoDB is...    | 2020-03-16 16:12:09 |         1 |
+----+-------------+------------------+---------------------+-----------+
5 rows in set (0.001 sec)

MariaDB [daco]> SELECT * FROM author;
+----+------+--------------------+
| id | name | profile            |
+----+------+--------------------+
|  1 | daco | developer          |
|  2 | ted  | data administrator |
|  3 | jin  | data scientist     |
+----+------+--------------------+
3 rows in set (0.000 sec)

# 잘 들어갔는지 확인, 잘 들어감~!

 

 

관계형 데이터베이스의 꽃 JOIN

 

테이블이 분리되어 있어도 하나의 테이블인 것처럼 만들어줌 (직관적으로 보여주기 위함)

아래는 실습코드

 

MariaDB [daco]> SELECT * FROM topic;
+----+-------------+------------------+---------------------+-----------+
| id | title       | description      | created             | author_id |
+----+-------------+------------------+---------------------+-----------+
|  1 | MySQL       | MySQL is...      | 2018-01-01 12:10:11 |         1 |
|  2 | Oracle      | Oracle is...     | 2018-01-03 13:10:11 |         1 |
|  3 | SQL server  | SQL is...        | 2018-01-31 10:10:11 |         2 |
|  4 | Postgre SQL | PostgreSQL is... | 2018-01-16 05:10:11 |         3 |
|  5 | MongoDB     | MongoDB is...    | 2020-03-16 16:12:09 |         1 |
+----+-------------+------------------+---------------------+-----------+
5 rows in set (0.000 sec)

MariaDB [daco]> SELECT * FROM topic LEFT JOIN author;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
# JOIN 을 할때는 그 기준을 명확히 제시해주어야 한다. ON ~~

MariaDB [daco]> SELECT * FROM topic LEFT JOIN author ON topic.author_id = author.id;
# 이렇게
+----+-------------+------------------+---------------------+-----------+------+------+--------------------+
| id | title       | description      | created             | author_id | id   | name | profile            |
+----+-------------+------------------+---------------------+-----------+------+------+--------------------+
|  1 | MySQL       | MySQL is...      | 2018-01-01 12:10:11 |         1 |    1 | daco | developer          |
|  2 | Oracle      | Oracle is...     | 2018-01-03 13:10:11 |         1 |    1 | daco | developer          |
|  3 | SQL server  | SQL is...        | 2018-01-31 10:10:11 |         2 |    2 | ted  | data administrator |
|  4 | Postgre SQL | PostgreSQL is... | 2018-01-16 05:10:11 |         3 |    3 | jin  | data scientist     |
|  5 | MongoDB     | MongoDB is...    | 2020-03-16 16:12:09 |         1 |    1 | daco | developer          |
+----+-------------+------------------+---------------------+-----------+------+------+--------------------+
5 rows in set (0.002 sec)
# 잘 조인 되었다

MariaDB [daco]> SELECT id,title,description,created,name,profile FROM topic LEFT JOIN author ON topic.author_id = author.id;
ERROR 1052 (23000): Column 'id' in field list is ambiguous
# author_id 와 author 테이블의 id를 숨기려고 한다. 위에 코드처럼 치지만 오류가 떴다. 
# 이유는 id 컬럼이 2개이기 때문에 정확하게 구분해서 알려달라는 에러다.



MariaDB [daco]> SELECT topic.id,title,description,created,name,profile FROM topic LEFT JOIN author ON topic.author_id = author.id;
# 그럴 때는 컬럼 이름 앞에 '테이블명.' 을 붙여주면 된다. 이건 다른 언어들과 동일한 듯



+----+-------------+------------------+---------------------+------+--------------------+
| id | title       | description      | created             | name | profile            |
+----+-------------+------------------+---------------------+------+--------------------+
|  1 | MySQL       | MySQL is...      | 2018-01-01 12:10:11 | daco | developer          |
|  2 | Oracle      | Oracle is...     | 2018-01-03 13:10:11 | daco | developer          |
|  3 | SQL server  | SQL is...        | 2018-01-31 10:10:11 | ted  | data administrator |
|  4 | Postgre SQL | PostgreSQL is... | 2018-01-16 05:10:11 | jin  | data scientist     |
|  5 | MongoDB     | MongoDB is...    | 2020-03-16 16:12:09 | daco | developer          |
+----+-------------+------------------+---------------------+------+--------------------+
5 rows in set (0.000 sec)
# 잘 나왔다




MariaDB [daco]> SELECT topic.id AS topic_id,title,description,created,name,profile FROM topic LEFT JOIN author ON topic.author_id = author.id;
# 이건 조인 테이블을 뽑으면서 id를 topic_id 로 컬럼명을 변경하며 뽑는 코드, 단 확인해보니 원본 컬렴명이 바뀌는 게 아닌 일시적으로 바꿔서 출력하는 것이다
+----------+-------------+------------------+---------------------+------+--------------------+
| topic_id | title       | description      | created             | name | profile            |
+----------+-------------+------------------+---------------------+------+--------------------+
|        1 | MySQL       | MySQL is...      | 2018-01-01 12:10:11 | daco | developer          |
|        2 | Oracle      | Oracle is...     | 2018-01-03 13:10:11 | daco | developer          |
|        3 | SQL server  | SQL is...        | 2018-01-31 10:10:11 | ted  | data administrator |
|        4 | Postgre SQL | PostgreSQL is... | 2018-01-16 05:10:11 | jin  | data scientist     |
|        5 | MongoDB     | MongoDB is...    | 2020-03-16 16:12:09 | daco | developer          |
+----------+-------------+------------------+---------------------+------+--------------------+
5 rows in set (0.000 sec)


MariaDB [daco]> UPDATE author SET profile='database administrator' WHERE id = 2;
Query OK, 1 row affected (0.003 sec)
Rows matched: 1  Changed: 1  Warnings: 0
# author 테이블의 데이터 하나가 잘못기재되어 profile 데이터를 수정했다.


MariaDB [daco]> SELECT topic.id AS topic_id,title,description,created,name,profile FROM topic LEFT JOIN author ON topic.author_id = author.id;
+----------+-------------+------------------+---------------------+------+------------------------+
| topic_id | title       | description      | created             | name | profile                |
+----------+-------------+------------------+---------------------+------+------------------------+
|        1 | MySQL       | MySQL is...      | 2018-01-01 12:10:11 | daco | developer              |
|        2 | Oracle      | Oracle is...     | 2018-01-03 13:10:11 | daco | developer              |
|        3 | SQL server  | SQL is...        | 2018-01-31 10:10:11 | ted  | database administrator |
|        4 | Postgre SQL | PostgreSQL is... | 2018-01-16 05:10:11 | jin  | data scientist         |
|        5 | MongoDB     | MongoDB is...    | 2020-03-16 16:12:09 | daco | developer              |
+----------+-------------+------------------+---------------------+------+------------------------+
5 rows in set (0.000 sec)
# 수정하고 다시 조인 테이블을 출력해보니 잘 반영되어 나온다.
# 이렇듯 테이블을 분리하는 것은 데이터 중복을 막고 데이터 수정을 간편하기 위함이다.
# 이것이 관계형 데이터베이스의 혁신이다!

 

 


 

 오늘 느낀 것 

 

<중요!>

# 테이블 이름 변경 방법 -> 리네임 테이블 (이름) 투 (새이름);
ex. RENAME TABLE topic TO topic_backup;

#DESC 는 설명을 뜻함. 즉, 테이블이 어떻게 설정되어있는 목록화 하여 보여주는 명령어

# 컬럼 수정 방법은 [ ALTER TABLE 테이블명 CHANGE 기존컬럼명 변경할컬럼평 컬럼타입; ]
ex. ALTER TABLE topic CHANGE titile title VARCHAR(30) NOT NULL;

# SHOW -> 테이블 목록을 가져옴
# SELECT -> 테이블 데이터를 가져옴

 

# JOIN 을 할때는 그 기준을 명확히 제시해주어야 한다. ON ~~
ex. SELECT * FROM topic LEFT JOIN author ON topic.author_id = author.id;

# 컬럼 이름 앞에 '테이블명.' 을 붙여주면 그 테이블의 하위 컬럼명을 지칭한다. (다른 언어들과 동일)
ex. SELECT topic.id,title,description,created,name,profile FROM topic LEFT JOIN author ON topic.author_id = author.id;

# 이건 조인 테이블을 뽑으면서 id를 topic_id 로 컬럼명을 변경하며 뽑는 방법 (원본 컬렴명이 바뀌는 게 아닌 조인시에만 바꿔서 출력)
ex. SELECT topic.id AS topic_id,title,description,created,name,profile FROM topic LEFT JOIN author ON topic.author_id = author.id;

# 테이블 내 데이터 수정방법
ex. UPATE author SET profile='database administrator' WHERE id = 2;

 

 

데이터 베이스 은근히 재밌다.

앞으로 머리가 꽤나 아플 듯..!

반응형