SQL - PRIMARY KEY, FOREIGN KEY

Yang HyunIl·2023년 2월 14일
0

SQL

목록 보기
11/14
post-thumbnail

🔴PRIMARY KEY (기본 키)

  • 테이블의 각 레코드를 식별
  • 중복되지 않은 고유값을 포함
  • NULL 값을 포함할 수 없음
  • 테이블 당 하나의 기본키를 가짐

생성

    1. 테이블 생성과 함께
CREATE TABLE tablename
(
	column1 datatype NOT NULL,
    column2 datatype NOT NULL,
    ...
    CONSTRAINT constraint_name # 생략시 자동생성 -> SHOW CREATE TABLE로 확인 가능
    PRIMARY KEY (column1, column2, ...)
);     
    1. 기존 테이블에서 생성
ALTER TABLE tablename
ADD PRIMARY KEY (column1, column2, ...);

예제 1

  • 하나의 칼럼을 기본키로 설정하는 경우
mysql> create table person                    
    -> (
    ->  pid int NOT NULL,
    ->  name varchar(16),
    ->  age int,
    ->  sex char,
    ->  primary key (pid)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc person;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| pid   | int         | NO   | PRI | NULL    |       |
| name  | varchar(16) | YES  |     | NULL    |       |
| age   | int         | YES  |     | NULL    |       |
| sex   | char(1)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
  • 여러개의 칼럼을 기본키로 설정하는 경우
mysql> create table animal
    -> (
    ->  name varchar(16) NOT NULL,
    ->  type varchar(16) NOT NULL,
    ->  age int,
    ->  primary key (name, type)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc animal;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(16) | NO   | PRI | NULL    |       |
| type  | varchar(16) | NO   | PRI | NULL    |       |
| age   | int         | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

예제 2

  • 하나의 컬럼을 기본키로 지정하는 경우
mysql> alter table person    
    -> add primary key (pid); 
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc person;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| pid   | int         | NO   | PRI | NULL    |       |
| name  | varchar(16) | YES  |     | NULL    |       |
| age   | int         | YES  |     | NULL    |       |
| sex   | char(1)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
  • 여러개의 컬럼을 기본키로 지정하는 경우
mysql> alter table animal
    -> add constraint PK_animal 
    -> primary key (name, type);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc animal;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(16) | NO   | PRI | NULL    |       |
| type  | varchar(16) | NO   | PRI | NULL    |       |
| age   | int         | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

삭제

ALTER TABLE tablename
DROP PRIMARY KEY;

예제

  • 하나의 컬럼이 기본키로 설정된 경우
mysql> alter table person
    -> drop primary key;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc person;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| pid   | int         | NO   |     | NULL    |       |
| name  | varchar(16) | YES  |     | NULL    |       |
| age   | int         | YES  |     | NULL    |       |
| sex   | char(1)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
  • 여러개의 컬럼이 기본키로 설정된 경우 (삭제 방법 동일)
mysql> alter table animal
    -> drop primary key;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc animal;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(16) | NO   |     | NULL    |       |
| type  | varchar(16) | NO   |     | NULL    |       |
| age   | int         | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

🔴FOREIGN KEY (외래키)

  • 한 테이블을 다른 테이블과 연결해주는 역할
  • 참조되는 테이블의 항복은 그 테이블의 기본키 (혹은 단일값)

CONSTRAINT 확인

SHOW CREATE TABLE tablename;
mysql> show create table job;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+      
| Table | Create Table

                                                                                               |      
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+      
| job   | CREATE TABLE `job` (
  `jid` int NOT NULL,
  `name` varchar(16) DEFAULT NULL,
  `pid` int DEFAULT NULL,
  PRIMARY KEY (`jid`),
  KEY `pid` (`pid`),
  CONSTRAINT `job_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `person` (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

생성

    1. 테이블 생성과 함께
CREATE TABLE tablename
(
	column1 datatype NOT NULL,
    column2 datatype NOT NULL,
    column3 datatype,
    column4 datatype,
    ...
    CONSTRAINT constraint_name
    PRIMARY KEY (column1, column2, ...),
    CONSTRAINT constraint_name
    FOREIGN KEY (column3, column4, ...) REFERENCES REF_tablename(REF_column)
);    
    1. 기존 테이블에서 생성
ALTER TABLE tablename
ADD FOREIGN KEY (column) REFERENCES REF_tablename(REF_column);

예제 1

mysql> create table orders   
    -> (
    ->  oid int not null,     
    ->  order_no varchar(16),
    ->  pid int,
    ->  primary key (oid),
    ->  constraint FK_person foreign key (pid) references person(pid)
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> desc orders;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| oid      | int         | NO   | PRI | NULL    |       |
| order_no | varchar(16) | YES  |     | NULL    |       |
| pid      | int         | YES  | MUL | NULL    |       |
+----------+-------------+------+-----+---------+-------+

예제 2

alter table orders
    -> add foreign key (pid) references person(pid);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc orders;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| oid      | int         | NO   | PRI | NULL    |       |
| order_no | varchar(16) | YES  |     | NULL    |       |
| pid      | int         | YES  | MUL | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> show create table orders;
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table


    |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| orders | CREATE TABLE `orders` (
  `oid` int NOT NULL,
  `order_no` varchar(16) DEFAULT NULL,
  `pid` int DEFAULT NULL,
  PRIMARY KEY (`oid`),
  KEY `pid` (`pid`),
  CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `person` (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

삭제

ALTER TABLE tablename
DROP FOREIGN KEY FK_constraint;

예제

mysql> alter table orders
    -> drop foreign key FK_person;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc orders;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| oid      | int         | NO   | PRI | NULL    |       |
| order_no | varchar(16) | YES  |     | NULL    |       |
| pid      | int         | YES  | MUL | NULL    |       |
+----------+-------------+------+-----+---------+-------+

mysql> show create table orders;
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table

                                  |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| orders | CREATE TABLE `orders` (
  `oid` int NOT NULL,
  `order_no` varchar(16) DEFAULT NULL,
  `pid` int DEFAULT NULL,
  PRIMARY KEY (`oid`),
  KEY `FK_person` (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

🔴분석

  • crime_status.police_station을 police_station.name과 같이 만들어서 비교
select c.police_station, p.name       
    -> from crime_status c, police_station p
    -> where p.name like concat ('서울', c.police_station, '경찰서') 
    -> group by c.police_station, p.name;
+----------------+--------------------------+
| police_station | name                     |
+----------------+--------------------------+
| 중부           | 서울중부경찰서           |
| 종로           | 서울종로경찰서           |
| 남대문         | 서울남대문경찰서         |
| 서대문         | 서울서대문경찰서         |
| 혜화           | 서울혜화경찰서           |
| 용산           | 서울용산경찰서           |
| 성북           | 서울성북경찰서           |
| 동대문         | 서울동대문경찰서         |
| 마포           | 서울마포경찰서           |
| 영등포         | 서울영등포경찰서         |
| 성동           | 서울성동경찰서           |
| 동작           | 서울동작경찰서           |
| 광진           | 서울광진경찰서           |
| 서부           | 서울서부경찰서           |
| 강북           | 서울강북경찰서           |
| 금천           | 서울금천경찰서           |
| 중랑           | 서울중랑경찰서           |
| 강남           | 서울강남경찰서           |
| 관악           | 서울관악경찰서           |
| 강서           | 서울강서경찰서           |
| 강동           | 서울강동경찰서           |
| 종암           | 서울종암경찰서           |
| 구로           | 서울구로경찰서           |
| 서초           | 서울서초경찰서           |
| 양천           | 서울양천경찰서           |
| 송파           | 서울송파경찰서           |
| 노원           | 서울노원경찰서           |
| 방배           | 서울방배경찰서           |
| 은평           | 서울은평경찰서           |
| 도봉           | 서울도봉경찰서           |
| 수서           | 서울수서경찰서           |
+----------------+--------------------------+

Primary Key 설정

  • police_station.name을 Primary Key로 설정
mysql> alter table police_station   
    -> add primary key(name);
Query OK, 31 rows affected (0.08 sec)
Records: 31  Duplicates: 0  Warnings: 0

mysql> desc police_station;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| name    | varchar(16)  | NO   | PRI | NULL    |       |
| address | varchar(128) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+

Foreign Key 설정

  • crime_status 테이블에 Foreign Key로 사용할 Column 추가
mysql> alter table crime_status
    -> add column reference varchar(16);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc crime_status;
+----------------+-------------+------+-----+---------+-------+
| Field          | Type        | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| year           | year        | YES  |     | NULL    |       |
| police_station | varchar(8)  | YES  |     | NULL    |       |
| crime_status   | varchar(16) | YES  |     | NULL    |       |
| status_type    | char(2)     | YES  |     | NULL    |       |
| case_number    | int         | YES  |     | NULL    |       |
| reference      | varchar(16) | YES  |     | NULL    |       |
+----------------+-------------+------+-----+---------+-------+
  • Foreign Key 생성
mysql> alter table crime_status
    -> add foreign key (reference) references police_station(name);
Query OK, 310 rows affected (0.11 sec)
Records: 310  Duplicates: 0  Warnings: 0

mysql> desc crime_status;
+----------------+-------------+------+-----+---------+-------+
| Field          | Type        | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| year           | year        | YES  |     | NULL    |       |
| police_station | varchar(8)  | YES  |     | NULL    |       |
| crime_status   | varchar(16) | YES  |     | NULL    |       |
| status_type    | char(2)     | YES  |     | NULL    |       |
| case_number    | int         | YES  |     | NULL    |       |
| reference      | varchar(16) | YES  | MUL | NULL    |       |
+----------------+-------------+------+-----+---------+-------+

Foreign Key 설정

  • Foreign Key 값 Update
mysql> update crime_status c, police_station p 
    -> set c.reference = p.name
    -> where p.name like concat('서울', c.police_station, '경찰서');
Query OK, 310 rows affected (0.06 sec)
Rows matched: 310  Changed: 310  Warnings: 0

mysql> select distinct police_station, reference from crime_status;
+----------------+--------------------------+
| police_station | reference                |
+----------------+--------------------------+
| 중부           | 서울중부경찰서           |
| 종로           | 서울종로경찰서           |
| 남대문         | 서울남대문경찰서         |
| 서대문         | 서울서대문경찰서         |
| 혜화           | 서울혜화경찰서           |
| 용산           | 서울용산경찰서           |
| 성북           | 서울성북경찰서           |
| 동대문         | 서울동대문경찰서         |
| 마포           | 서울마포경찰서           |
| 영등포         | 서울영등포경찰서         |
| 성동           | 서울성동경찰서           |
| 동작           | 서울동작경찰서           |
| 광진           | 서울광진경찰서           |
| 서부           | 서울서부경찰서           |
| 강북           | 서울강북경찰서           |
| 금천           | 서울금천경찰서           |
| 중랑           | 서울중랑경찰서           |
| 강남           | 서울강남경찰서           |
| 관악           | 서울관악경찰서           |
| 강서           | 서울강서경찰서           |
| 강동           | 서울강동경찰서           |
| 종암           | 서울종암경찰서           |
| 구로           | 서울구로경찰서           |
| 서초           | 서울서초경찰서           |
| 양천           | 서울양천경찰서           |
| 송파           | 서울송파경찰서           |
| 노원           | 서울노원경찰서           |
| 방배           | 서울방배경찰서           |
| 은평           | 서울은평경찰서           |
| 도봉           | 서울도봉경찰서           |
| 수서           | 서울수서경찰서           |
+----------------+--------------------------+

JOIN

  • Foreign Key를 기준으로 두 테이블을 연관시켜 검색
mysql> select c.police_station, p.address
    -> from crime_status c, police_station p 
    -> where c.reference = p.name
    -> group by c.police_station;
+----------------+----------------------------------------------------------------------------------+
| police_station | address                                                                          | 
+----------------+----------------------------------------------------------------------------------+ 
| 강남           | 서울특별시 강남구 테헤란로 114길 11                                              | 
| 강동           | 서울특별시 강동구 성내로 33                                                      | 
| 강북           | 서울특별시 강북구 오패산로 406                                                   | 
| 강서           | 서울특별시 양천구 화곡로 73                                                      | 
| 관악           | 서울특별시 관악구 관악로5길 33                                                   |
| 광진           | 서울특별시 광진구 광나루로 447 광진소방서 임시청사 (능동)                        | 
| 구로           | 서울특별시 구로구 가마산로 235                                                   | 
| 금천           | 서울특별시 관악구 남부순환로 1435                                                | 
| 남대문         | 서울특별시 중구 한강대로 410                                                     |
| 노원           | 서울특별시 노원구 노원로 283                                                     | 
| 도봉           | 서울특별시 도봉구 노해로 403                                                     | 
| 동대문         | 서울특별시 동대문구 약령시로 21길 29                                             | 
| 동작           | 서울특별시 동작구 노량진로 148                                                   |
| 마포           | 서울특별시 마포구 마포대로 183                                                   | 
| 방배           | 서울특별시 서초구 방배천로 54                                                    | 
| 서대문         | 서울특별시 서대문구 통일로 113                                                   | 
| 서부           | 서울특별시 은평구 은평로9길 15                                                   |
| 서초           | 서울특별시 서초구 반포대로 179                                                   | 
| 성동           | 서울특별시 성동구 왕십리광장로 9                                                 | 
| 성북           | 서울특별시 성북구 보문로 170                                                     | 
| 송파           | 서울특별시 송파구 중대로 221                                                     | 
| 수서           | 서울특별시 강남구 개포로 617                                                     | 
| 양천           | 서울특별시 양천구 목동동로 99                                                    |
| 영등포         | 서울특별시 영등포구 국회대로 608                                                 | 
| 용산           | 서울특별시 용산구 원효로89길 24                                                  | 
| 은평           | 서울특별시 은평구 연서로 365                                                     | 
| 종로           | 서울특별시 종로구 율곡로 46                                                      | 
| 종암           | 서울특별시 성북구 종암로 135                                                     |
| 중랑           | 서울특별시 중랑구 중랑역로 137                                                   | 
| 중부           | 서울특별시 중구 수표로 27                                                        | 
| 혜화           | 서울특별시 종로구 창경궁로 112-16                                                | 
+----------------+----------------------------------------------------------------------------------+
profile
ヾ(•ω•`)o

0개의 댓글