1. 제약조건

데이터 무결성을 목적으로 SQL에서는 몇 가지 제약조건을 제공하고 있음.

PRIMARY KEY 데이터를 구분할 수 있께 하는 식별자 (NULL 불가)
FOREIGN KEY 두 테이블 사이의 관계를 연결 (기본 키와 대응)
UNIQUE 중복되지 않는 유일한 값을 입력 (NULL 허용)
CHECK 입력되는 데이터가 조건에 부합하는지 점검
DEFAULT 값을 입력하지 않았을 때 입력되는 값을 미리 지정
NULL NULL값이 입력되는 것을 허용

 

1) PRIMARY KEY (기본키)

기본키는 데이터를 구분할 수 있게 하는 식별자로 중복,NULL값 입력이 불가능함. 한 테이블에 하나의 기본키를 설정할 수 있음. (두 개 이상의 기본키 지정 불가.)

 

- 테이블을 만들면서 기본키를 지정

CREATE TABLE table1
(column1 CHAR(8) NOT NULL
...
PRIMARY KEY (column1)
); --column1이 기본키로 지정됨
CREATE TABLE table2
(column2 CHAR(8) NOT NULL PRIMARY KEY,
...
);
-- column2가 기본키로 지정됨

- 테이블을 만든 후에 사후적으로 기본키를 지정

ALTER RABLE table3 ADD CONSTRAINT PRIMARY KEY (column3);
-- column3을 기본키로 지정

 

2) FOREIGN KEY (외래키)

외래키는 두 테이블 사이의 관계를 연결해줌으로서 데이터의 무결성을 보장함. 외래키가 설정된 열은 다른 테이블의 기본키와 연결되며, 기본키가 있는 테이블과 외래키로 연결된 테이블은 기준테이블과 참조테이블의 관계를 가지게 됨. (참조 테이블의 외래키는 항상 기준 테이블의 기본키로 존재함. 고유키도 가능)

 

- 테이블을 만들면서 외래키를 지정

CREATE TABLE table1
(...
FOREIGN KEY (column1) REFERENCES member(column1)
);

- 테이블을 만든 후에 사후적으로 외래키를 지정

CREATE table2 buy 
(...); -- 테이블을 만듦.

ALTER TABLE table2
ADD CONSTRAINT
FOREIGN KEY(column2)
REFERENCES tabl3(column2); -- table2가 table3의 기본키를 참조하는 외래키 column2를 가짐.

cf) 기본키-외래키 관계가 정해진 후 기준 테이블의 기본키 열 이름 변경

참조 테이블에 해당 열의 데이터가 존재하는 경우 기준테이블만 단독적으로 열 이름을 변경할 수 없으며 참조 테이블의 열 이름도 함께 바뀌어야 함. 이때 ON UPDATE/DELETE CASCADE() 문을 사용.

-- table4는 참조테이블, table5는 기준테이블

ALTER TABLE table4
ADD CONSTRAINT
FOREIGN KEY(column4)
REFERENCES table5(column4)
ON UPDATE CASCADE
ON DELETE CASCADE;

 

3) UNIQUE (고유키)

고유키는 중복되지 않는 유일한 값을 입력해야 하는 조건으로, 기본키와 유사해보이나 기본키와 다르게 NULL값을 허용하고 한 테이블에 여러개의 고유키를 사용할 수 있음.

CREATE TABLE table1
( ...
email CHAR(30) NULL UNIQUE
);

 

4) CHECK (조건)

체크는 입력되는 데이터가 특정 조건에 부합하는지 점검함.

CREATE TABLE member
( ...
height TINYINT UNSIGNED NULL CHECK (height>=100),
...
);
-- 멤버의 키 데이터가 100 이상일때만 입력을 받음.
ALTER TABLE member
ADD CONSTRAINT
CHECK (phonenumber1 IN (‘02’,‘031’,‘032’,‘054’,...));
-- 멤버의 전화번호 데이터가 특정 입력값일때만 입력을 허용함.

 

5) DEFAULT (기본값)

디폴트는 값을 입력하지 않았을 때 자동으로 입력될 값을 미리 저장해 놓는 방법임.

CREATE TABLE member
(
...
height TINYINT UNSIGNED NULL DEFAULT 160
);
-- 사용자가 height 값을 입력하지 않을시 자동으로 160으로 설정함.
ALTER TABLE member
	ALTER COLUMN phonenumber1 SET DEFAULT ‘02’;

INSERT INTO member VALUES (... , ... , DEFAULT);
-- 사용자가 번호를 입력하지 않을시 자동으로 02로 설정함. 이때 해당 입력값에 'DEFAULT'를 입력해줘야 정상적으로 지정됨.

 

2. 뷰

뷰는 테이블과 유사하나 테이블처럼 실제로 데이터를 가지고 있지는 않으며, 사용자가 원하는 방식으로 테이블의 내용을 보여주는 일종의 가상 테이블임. 데이터 보안과 간결한 SQL문을 목적으로 사용함.

 

1) 생성 및 조회

CREATE VIEW view1
AS
SELECT column1, column2, column3 FROM table;

SELECT *FROM view1;

 

2) 수정

CREATE VIEW view1
AS
SELECT column1, column2, column3 FROM table;


ALTER VIEW view1
AS
SELECT column4, column5 FROM table1;

해당 코드를 수행하면 view1은 table1의 column1, 2, 3을 참조하는 것에서 4, 5를 참조하는 것으로 바뀜.

 

3) 삭제

DROP VIEW v_viewtest1;

DROP VIEW view1;

 

4) 생성 정보 확인

DESCRIBE view2; -- 생성 정보 확인 가능
SHOW CREATE VIEW view2; -- 소스코드 확인 가능

cf) DESCRIBE로 PREMARY KEY 등의 정보는 알 수 없음

 

5) 뷰를 이용한 테이블 데이터 변경

 

① 입력

INSERT INTO 
v_member(mem_id, mem_name, mem_number, addr) 
VALUES ('HONG','홍길동',1,'서울'); -- member테이블의 view v_member에 데이터 입력

SELECT * FROM member; -- 조회하면 테이블에서도 해당 데이터 확인 가능

 

② 수정

UPDATE v_member SET addr='인천' where mem_id='HONG';

 

③ 삭제

DELETE FROM member WHERE mem_number<10;

 

 

cf) VIEW 생성시 WHERE문을 이용하여 특정 조건만 테이블에서 가져오도록 설정이 가능

cf) VIEW 생성시 'WITH CHECK OPTION' 을 SELECT문 뒤에 입력하여 해당 조건에 어긋나면 INSERT를 받지 못하도록 설정이 가능

cf) 뷰가 참조하는 테이블이 삭제되면 해당 VIEW도 조회 불가하며  'CHECK TABLE view;'로 view가 참조하는 테이블의 상태를 확인할 수 있음.

한빛출판사 우재남 저 <혼자 공부하는 SQL>을 참고하여 작성하였습니다.

 

1. 데이터 형식

테이블의 열을 만들 때는 데이터 형식을 지정해주어야 함. 대표적인 데이터 형식 예로는 정수형, 문자형, 실수형, 날짜형 등이 있음.

 

1 ) INT (정수형)

TINYINT : -128 ~ 127 (1바이트)

SMALLINT : -32,768 ~ 32,767 (2바이트)

INT : 약 -21~ 21억 (4바이트)

BIGINT : 약 - 900~ 900경 (8바이트)

 

cf) UNSIGNED

값의 범위가 0부터 시작하여 만약 데이터 타입을 ‘TINYINT UNSIGNED’로 선언하면 0부터 255까지 범위를 표현할 수 있음. (UNSIGNED를 사용하지 않으면 127까지만 가능)

CREATE TABLE member (height TINYINT UNSIGNED);
INSERT INTO member values (200);

2) CHAR (문자형)

CHAR (개수)  : 255자까지 

개수보다 작은 문자가 저장되어도 개수만큼 자리를 확보하기 때문에 남은 자리를 낭비함.

VARCHAR (개수)  : 16383자까지

가변길이 문자형으로, 입력한 개수만큼만 자리를 확보하여 낭비가 없으나 CHAR보다 속도가 느림.

CREATE TABLE member (
mem_id VARCHAR(10), -- 몇 글자가 입력될 지 모름
mem_adddr CHAR(2) -- 서울, 경기, 경남처럼 항상 2글자로 입력
)

3) 실수형

FLOAT (4바이트) 소수점 아래 7자리까지

DOUBLE (8바이트) 소수점 아래 15자리까지

 

4) 날짜형

DATE : YYYY-MM-DD (3바이트)

TIME : HH:MM:SS (3바이트)

DATETIME : YYYY-MM-DD HH:MM:SS (8바이트)

 

5)변수의 사용

SET @var1 = 3;
SET @var2 = 5;

SELECT @var1;
SELECT @var1 + @var2;

'SET @변수이름 = ;' 으로 선언하고 'SELECT @변수이름'으로 사용함.

 

cf) LIMIT & PREPARE & EXECUTE

  LIMIT에는 변수를 사용할 수 없기 때문에 PREPARE과 EXECUTE로 아래처럼 우회하여 사용한다.

SET @cnt = 3;
PREPARE mySQL FROM 'SELECT mem_name, height FROM member ORDER BY height LIMIT ?';
EXECUTE mySQL USING @cnt;

 

6) 데이터 형 변환

① 명시적 변환

CAST() 함수나 CONVERT() 함수를 이용하여 형 변환. 여기에 올 수 있는 데이터 형식으로는 CHAR, SIGNED(부호가 있는 정수), UNSIGNED(부호가 없는 정수), DATE, TIME, DATETIME 등이 있음.

SELECT CAST(float_data AS SIGNED) FROM table1;
SELECT CONVERT(float_data, SIGNED) FROM table2;

암시적 변환

SELECT CONCAT(100,200); --정수 100, 200이 문자열 '100','200'으로 형변환
SELECT 100+'200'; -- '200' 문자열이 정수 200으로 형변환

cf) CONCAT() 함수는 문자열을 이어줌.

 

2. JOIN

두 테이블을 어떤 기준으로 합칠 수 있음.

 

1) 내부 조인

두 테이블에 모두 있는 내용만 조인 되며, 테이블이 일대다 관계로 연결되어 있어야 함. 따라서 내부 조인 된 테이블에는 NULL이 존재하지 않음.

SELECT * FROM buy
INNER JOIN member -- 구매목록 테이블과 회원 테이블을 INNER JOIN 함.
ON member.mem_id=buy.mem_id -- mem_id 열을 기준으로 JOIN.
WHERE buy.mem_id=""; -- 특정 mem_id를 가진 행만 출력할 수도 있음.

만약 mem_id 구매 내역별로 회원 정보를 붙여 확인하고 싶다면 위와 같이 내부 조인하여 확인이 가능.

 

2) 외부 조인

한 쪽 테이블에만 내용이 있어도 조인 가능. 'LEFT OUTER JOIN'은 왼쪽 테이블의 내용을 모두 출력하고, 'RIGHT OUTER JOIN'은 오른쪽 테이블의 내용을 모두 출력함. 'FULL OUTER JOIN'은 자주 사용하지는 않으나 왼쪽이든 오른쪽이든 한 쪽에 들어 있는 내용이면 출력함.

SELECT M.mem_id, M.mem_name, B.prod_name, M.addr
FROM member M
LEFT OUTER JOIN buy B -- member 테이블 기준으로 JOIN함. prod_name 열에 null값이 나올 수 있음.
ON M.mem_id = B.mem_id --mem_id 기준으로 JOIN
ORDER BY M.mem_id; -- mem_id 순으로 정렬

RIGHT OUTER JOIN으로 바꾸고 두 테이블의 순서를 바꾸면 같은 내용이 출력됨.

 

3) 상호 조인

상호 조인은 한 테이블의 모든 행과 다른 테이블의 모든 행을 조인시키는 기능을 하는데, 랜덤으로 조인하여 결과는 큰 의미가 없음.

SELECT * FROM buy CROSS JOIN member;

 

4) 자체 조인

한 테이블 안에서 조인이 일어난다.

CREATE TABLE emp_table (emp CHAR(4), manager CHAR(4), phone VARCHAR(4));

-- INSERT...

SELECT A.emp '직원', B.emp '직속 상관', B.phone '직속 상관 연락처'
FROM emp_table A
INNER JOIN emp_table B
ON A.manager = B.emp
-- WHERE A.emp = ''; //특정 직원을 지정하여 상관과 상관 연락처를 확인할수도 있음.

첫 번째 emp_table의 상관과 두 번째 emp_table의 직원이 같으면 직원, 직원의 상관, 상관의 연락처를 동시에 출력함. (기존 테이블에 직속 상관 연락처 열이 없었음에도 불구하고!)

한빛출판사 우재남 저 <혼자 공부하는 SQL>을 참고하여 작성하였습니다.

 

1. SELECT

1) 기본 형식 : SELECT  열 이름  FROM +테이블 이름

SELECT * FROM member;
SELECT mem_name FROM member;

 1번째 줄 : member 테이블의 모든 열을 출력함.

 2번째 줄: member 테이블의 mem_id 열을 출력함.

 

cf) 만약 선택된 데이터 베이스가 있다면 SELECT * FROM member; 와 같이 사용이 가능하지만 없다면 SELECT * FROM market_db.member;처럼 데이터베이스를 지정해줘야 함

 

2) 특정 조건만 조회하기 : SELECT ~ FROM ~WHERE

SELECT * FROM member WHERE mem_name='홍길동';

 

 WHRER 뒤에는 행 이름을 조건식으로 지정해줄 수 있음. 위 같은 경우 member 테이블에서 이름이 홍길동인 사람의 모든 열 내용을 출력함.

 

cf) 조건식에 관계 연산자와 논리 연산자 사용하기

-관계 연산자의 예시 : >,<,>=,<=,=

 ex) SELECT mem_id, mem_name FROM member WHERE height<=n;

member 테이블에서 키가 n보다 작거나 같다는 조건에 해당하는 행의 mem_idmem_name을 출력함.

 

-논리 연산자의 예시 : AND, OR

 ex) SELECT mem_id, mem_name FROM member WHERE height<=n and mem_number>6;

member 테이블에서 키가 n보다 작거나 같고, mem_numbern보다 작다는 조건에 해당하는 행의 mem_idmem_name을 출력함.

 

cf) 관계 연산자의 범위 지정 : BETWEEN ~ AND ~

SELECT mem_name, height FROM member WHERE height>=163 and height<=165;
SELECT mem_name, height FROM member WHERE height BETWEEN 163 AND 165;

 BETWEEN ~ AND ~ 를 이용하여 관계 연산자의 범위를 지정할 수 있음. 위 내용의 경우 첫번째 줄과 두번째 줄이 같은 내용을 출력함.

 

cf) 논리 연산자 간결하게 표현하기 : IN

SELECT mem_name, addr FROM member WHERE addr='서울' or addr='경기';
SELECT mem_name, addr FROM member WHERE addr IN('서울','경기');

 IN을 이용하면 논리 연산자가 여러 개 붙는 경우 연산자를 모두 작성하지 않고 간결하게 표현할 수 있음. 위 내용의 경우 첫번째 줄과 두번째 줄이 같은 내용을 출력함.

 

cf)LIKE

SELECT * FROM member WHERE mem_name LIKE '우%';
SELECT * FROM member WHERE mem_name LIKE '__우';

 

  LIKE는 문자열에 특정 글자를 포함하여 검색하고 싶을 때 사용함. 특정 글자로 시작하는 경우를 검색하고 싶을 때는 %를 사용하고, 특정 글자로 끝나는 경우를 검색하고 싶다면 __을 사용. 첫번째 줄의 경우 mem_name이 우로 시작하는 경우를 출력하며 두번째 줄의 경우 mem_name이 우로 끝나는 경우를 출력.

 

cf) 데이터 복사하기 : INSERT INTO SELECT FROM

INSERT INTO table1 SELECT column1, column2 FROM db.table2;

 테이블2의 열1, 열2가 테이블1의 데이터로 복사됨. 모든 열을 가져오려면 '*'을 사용.

 

 

2. CREATE

CREATE TABLE table1 (column1, column2, column3);

column1, 2, 3을 열로 하는 테이블 table1이 만들어짐. 이때 열마다의 자료형을 명시해야 하며 구분자인 PK(Primary Key) 및 NOT NULL 등의 속성을 지정해야함.

 

cf) AUTO_INCREMENT

CREATE TABLE member (mem_id INT AUTO_INCREMENT PRIMARY KEY, mem_name CHAR(4), age INT);

 -테이블을 만들 때 다음과 같이 AUTO_INCREMENT를 설정하면 열 값이 자동으로 1씩 증가함.

 -'SELECT LAST_INSERT_ID();'를 이용하여 어디까지 증가했는지 확인.

 -'@@auto_increment_increment=n;' 를 이용하여 n씩 증가하도록 조정.

 -'ARTER TABLE 테이블 이름 AUTO_INCREMENT = n'을 이용하여 시작값을 n으로 조정.

 

3. INSERT

INSERT INTO TABLE (column1, column2, column3) VALUES (value1, value2, value3);

 열 순서대로 저장한다면 (column1, column2, column3) 부분은 생략 가능.

 

4. ORDER BY, LIMIT, DISTINCT, GROUP BY, HAVING

1) ORDER BY & LIMIT

 ORDER BY 절은 결과가 출력되는 순서를 조절함.

SELECT mem_id, mem_name FROM member ORDER BY mem_id;
SELECT mem_id, mem_name FROM member ORDER BY mem_id DESC; -- 내림차순
SELECT mem_id, mem_name FROM member ORDER BY mem_id ASC; -- 오름차순

 예컨대 위와 같은 경우 mem_id, mem_name을 출력하는데 이때 정렬 기준을 mem_id의 가나다순으로 설정함.

 ASC, DESC를 붙여주면 순서대로 오름차순, 내림차순으로 정렬하라고 요구할 수 있음.

 정렬 기준을 여러 개 사용할 때는 ‘,’로 구분하며 이때 앞에 있는 정렬 기준이 우선적으로 고려됨.

 

SELECT * FROM member LIMIT 3;

LIMIT 절은 출력되는 개수를조절. 위와 같이 실행하면 member의 모든 열을 포함하는 3개의 행이 출력될 것.

 

SELECT * FROM member ORDER BY mem_id LIMIT 4,5;

  ORDER 절은 LIMIT절과 함께 자주 사용.

 위와 같이 입력하면 member 테이블을 mem_id의 가나다순으로 정렬하고 4번째 행을 시작으로 5개 행을 출력.

 

2) DISTINCT

SELECT DISTINCT addr FROM member;

 열 이름 앞에 DISTINCT를 써주면 중복된 데이터를 1개만 남기고 출력함. 따라서 DISTINCT를 사용하면 해당 열에 어떤 입력 값들이 존재하는지 쉽게 확인이 가능.

 

3) GROUP BY & HAVING

GROUP BY는 뒤에 나오는 열을 기준으로 데이터를 그룹으로 묶어주는 역할을 한다.

SELECT mem_id, amount FROM buy ORDER BY mem_id;
SELECT mem_id, SUM(amount) FROM buy GROUP BY mem_id;

 buy 테이블에 member id 별로 구매한 상품의 양(amount)이 저장되어 있다고 할 때, 

 첫번째처럼 명령어를 입력하면 한 회원이 여러 차례 나누어 구매한 경우가 모두 따로 출력.

 두번째처럼 명령어를 입력하면 회원별로 구매한 양을 합쳐 출력.

 

cf) 집계함수의 종류

 SUM() - 합계

 AVG() - 평균

 MAX() - 최댓값

 COUNT() - 행의 개수

 COUNT(DISTINCT) - 중복을 제외한 행의 개수

 

SELECT mem_id, SUM(price*amount) FROM buy GROUP BY mem_id HAVING SUM(price*amount)>=1000;

 HAVINGWHERE문과 유사한 역할을 수행.

 집계함수를 사용하면 WHERE을 사용할 수 없기 때문에 WHERE 대신 HAVING을 사용.

 위 명령문의 경우 mem_id와 mem_id별 총 구매 금액을 구한 뒤 총 구매 금액이 1000이 넘어가는 경우를 출력.

 

5. UPDATE

UPDATE SET mem_id='홍길동' WHERE mem_id='김길동';

 UPDATE 문은 테이블에 이미 입력되어있는 값을 수정할 때 사용.

 mem_id가 '김길동'인 곳을 찾아 값을 '홍길동'으로 바꿈.

 이때 WHERE문을 사용하지 않으면 모든 열의 값이 다 바뀌어버리니 주의!

 

6.DELETE

DELETE member WHERE mem_id='홍길동';

 DELETE문은 테이블에서 값을 삭제할 때 사용.

 

 

 

+ Recent posts