ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [MySQL] 테이블 분리와 JOIN
    생활코딩/DataBase 2020. 9. 28. 15:35

    [강의 출처] opentutorials.org/course/3161

     

    DATABASE2 - MySQL - 생활코딩

    수업소개 무료이면서, 오픈소스이고, 3대 데이터베이스 중에 하나인 MySQL의 입문 수업입니다.  수업대상 정보기술의 심장인 데이터베이스가 어떻게 동작하는지 궁금하신 분 데이터를 보다 전�

    opentutorials.org


    관계형 데이터베이스의 쓸모

    아래와 같은 데이터가 있다고 할 때,

    id
    1 고양이 고양이과 식육목 동물계
    2 장미 장미과 장미목 식물계
    3 퓨마 고양이과 식육목 동물계
    4 보르네오구름표범 고양이과 식육목 동물계

    여기서 '식육목', '동물계'는 '고양이과'의 상위 항목이므로, '고양이과'에 따라오는 데이터이고,

    '장미목', '식물계'는 '장미과'에 따라오는 데이터다.

    이런 상황에서는 '목' 컬럼의 데이터를 영어 명칭으로 바꿔야 되는 경우, 모든 '목' 데이터를 다 건드려야하므로 대참사가 일어날 수 있다.

    따라서 이렇게 따라오는 데이터, 즉 종속 데이터가 있는 경우, 아래처럼 표를 분리하는 편이 바람직하다.

    id 과_id
    1 고양이 1
    2 장미 2
    3 퓨마 1
    4 보르네오구름표범 1
    과_id
    1 고양이과 식육목 동물계
    2 장미과 장미목 식물계

    이 경우 '목' 컬럼의 데이터를 변경해야 하는 경우가 있더라도 아래 표에서만 변경하면 되고, 위 표에서는 과_id를 참조해 처리하면 된다.

    분리는 이렇게 하면 된다.

     

    기존 테이블 생성 구문

    mysql> CREATE TABLE gray(id int(11) NOT NULL AUTO_INCREMENT, species VARCHAR(30) NOT NULL
    , family VARCHAR(30) NOT NULL, _order VARCHAR(30) NOT NULL, kingdom VARCHAR(30) NOT NULL,
     PRIMARY KEY(id));
     
    mysql> INSERT INTO gray (species, family, _order, kingdom) 
    VALUES ('cat', 'Felidae', 'Carnivora', 'Animalia'),
    ('rose', 'Rosaceae', 'Rosales', 'Plantae'),
    ('puma', 'Felidae', 'Carnivora', 'Animalia'),
    ('Sunda clouded leopard', 'Felidae', 'Carnivora', 'Animalia');
    
    +----+-----------------------+----------+-----------+----------+
    | id | species               | family   | _order    | kingdom  |
    +----+-----------------------+----------+-----------+----------+
    |  1 | cat                   | Felidae  | Carnivora | Animalia |
    |  2 | rose                  | Rosaceae | Rosales   | Plantae  |
    |  3 | puma                  | Felidae  | Carnivora | Animalia |
    |  4 | Sunda clouded leopard | Felidae  | Carnivora | Animalia |
    +----+-----------------------+----------+-----------+----------+

    기존 테이블을 분리하는 구문

    mysql> CREATE TABLE green1 SELECT id, species, family FROM gray;      -- 위의 표 green1 생성
    
    mysql> CREATE TABLE green2 SELECT id, family, _order, kingdom FROM gray;  -- 아래 표 green2 생성
    mysql> DELETE tb1 FROM green2 tb1, green2 tb2              
    WHERE tb1.family = tb2.family AND tb1._order = tb2._order
    AND tb1.kingdom = tb2.kingdom AND tb1.id < tb2.id;   -- green2 중복 제거  
    
    mysql> UPDATE green1 INNER JOIN green2 ON green1.family = green2.family
    SET green1.family = green2.id;               -- green1의 family를 green2의 id값으로 치환
    
    ALTER TABLE green1 CHANGE family familyID INT(11);   -- 헷갈리니까 green1 family컬럼명도 변경
    
    mysql> SELECT * FROM green1;
    +----+-----------------------+----------+
    | id | species               | familyID |
    +----+-----------------------+----------+
    |  1 | cat                   |        4 |
    |  2 | rose                  |        2 |
    |  3 | puma                  |        4 |
    |  4 | Sunda clouded leopard |        4 |
    +----+-----------------------+----------+
    
    mysql> SELECT * FROM green2;
    +----+----------+-----------+----------+
    | id | family   | _order    | kingdom  |
    +----+----------+-----------+----------+
    |  2 | Rosaceae | Rosales   | Plantae  |
    |  4 | Felidae  | Carnivora | Animalia |
    +----+----------+-----------+----------+

     

    표를 분리해둔 상태에서, 맨위의 회색 표처럼 출력하고 싶다면 JOIN문을 이용하면 된다.

     

    JOIN

    mysql> SELECT * FROM green1 LEFT JOIN green2 ON green1.familyID = green2.id;
    +----+-----------------------+----------+------+----------+-----------+----------+
    | id | species               | familyID | id   | family   | _order    | kingdom  |
    +----+-----------------------+----------+------+----------+-----------+----------+
    |  2 | rose                  |        2 |    2 | Rosaceae | Rosales   | Plantae  |
    |  1 | cat                   |        4 |    4 | Felidae  | Carnivora | Animalia |
    |  3 | puma                  |        4 |    4 | Felidae  | Carnivora | Animalia |
    |  4 | Sunda clouded leopard |        4 |    4 | Felidae  | Carnivora | Animalia |
    +----+-----------------------+----------+------+----------+-----------+----------+

    id가 출력되는 것이 보기 싫다면 직접 원하는 컬럼을 지정해줄 수도 있다.

    mysql> SELECT green1.id, green1.species, green2.family, green2._order, green2.kingdom
    FROM green1 LEFT JOIN green2 ON green1.familyID = green2.id;
    +----+-----------------------+----------+-----------+----------+
    | id | species               | family   | _order    | kingdom  |
    +----+-----------------------+----------+-----------+----------+
    |  2 | rose                  | Rosaceae | Rosales   | Plantae  |
    |  1 | cat                   | Felidae  | Carnivora | Animalia |
    |  3 | puma                  | Felidae  | Carnivora | Animalia |
    |  4 | Sunda clouded leopard | Felidae  | Carnivora | Animalia |
    +----+-----------------------+----------+-----------+----------+

    출력 컬럼명을 바꾸고 싶다면 AS, 정렬이 필요하다면 ORDER BY를 쓰면 된다.

    ysql> SELECT green1.id, green1.species, family, _order AS orders, kingdom
    FROM green1 LEFT JOIN green2 ON green1.familyID = green2.id ORDER BY id ASC;
    +----+-----------------------+----------+-----------+----------+
    | id | species               | family   | orders    | kingdom  |
    +----+-----------------------+----------+-----------+----------+
    |  1 | cat                   | Felidae  | Carnivora | Animalia |
    |  2 | rose                  | Rosaceae | Rosales   | Plantae  |
    |  3 | puma                  | Felidae  | Carnivora | Animalia |
    |  4 | Sunda clouded leopard | Felidae  | Carnivora | Animalia |
    +----+-----------------------+----------+-----------+----------+

     

     

    댓글

Designed by Tistory.