Mysql 문법
DELETE
문법 : DELETE [LOW_PRIORITY] FROM tbl_name [WHERE where_definition] [LIMIT rows]
DELETE 는 주어진 조건에 맞는 행을 삭제한 후 삭제 된 행의 수를 리턴한다.
만일 WHERE 조건 절을 생략하면 모든 행이 삭제 된다. 이 경우 MySQL 은 먼저 같은 이름의 빈 테이블을 새롭게 만드는데 이 방법이 각각의 행을 지우는 것보다 빠르기 때문이다. 이때 지워진 행의 수는 0 을 리턴한다.
만일 시간이 좀더 걸리더라도 몇 개의 행이 삭제 되었는지 알고 싶다면 WHERE 절을 생략하지 말고 다음과 같이 항상 참인 내용을 적어 주면 된다.
mysql> DELETE FROM tbl_name WHERE 1>0;
이 경우 당연히 WHERE 절을 생략한 채 모두 지우는 것보다 훨씬 느리게 된다.
만일 LOW_PRIORITY 키워드를 사용하면 모든 사용자가 해당 테이블의 사용을 끝낼 때까지 DELETE 의 실행이 지연된다.
지 워진 데이터 영역은 새롭게 추가 되는 데이터들에 의해 불연속적으로 채워지게 되므로 OPTIMIZE TABLE 명령과 isamchk 유틸리티를 이용하면 속도가 향상된다. OPTIMIZE TABLE 은 사용이 쉬운 반면 isamchk 유틸리티는 복구 속도가 빠르다 .
MySQL에서만 사용이 가능한 LIMIT 키워드를 사용해 한번에 삭제할 행의 수를 지정해 줄수 있다. 이는 얼마나 많은 자료가 삭제될지 예측할 수 없는 경우 시간절약을 위해 사용될 수 있다. 물론 LIMIT를 반복해서 사용하면 조건에 맞는 모든 자료를 삭제 할 수 있다.
다중삭제
- delete one, two from one, two where one.id = two.id;
SELECT
문법 : SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [DISTINCT | ALL]
SELECT 는 하나 이상의 테이블에서 데이터를 가져올 때 사용 된다.
select_expression 은 데이터를 가져올 컬럼을 나타낸다. SELECT 문을 테이블의 컬럼이 아닌 단순한 연산이나 함수의 결과를 나타낼 때에도 사용된다.
모든 키워드는 위의 사용법에 나온 순서대로 나와야 한다. 예를 들어 HAVING 절은 반드시 GROUP BY 뒤와ORDER BY 사이에 나와야만 한다.
- AS를 이용해 컬럼명을 별명(alias)으로 쓸 수 있다. 별명은 ORDER BY 또는 HAVING 절에서도 사용가능하다.
mysql> select concat(last_name,’, ‘,first_name) AS full_name from mytable ORDER BY full_name;
- FROM table_references 는 데이터를 가져올 테이블을 나타낸다. 만일 두개 이상의 테이블을 이용할 경우는 조인을 해야만 할 것이다.
- 컬럼명은col_name, tbl_name.col_name , db_name.tbl_name.col_name 과 같은 방법으로 참조 할 수 있다 . 그러나 두개 이상의 테이블에서 공통적으로 존재하는 컬럼을 사용하는 경우가 아니라면 생략해도 무방하다.
데이터의 정렬을 위해 ORDER BY , GROUP BY 절에서는 컬럼명 , 컬럼의 별명, 컬럼 인덱스(1부터 시작)를 사용할 수 있다.
- select college, region, seed from tournament ORDER BY region, seed
- select college, region AS r, seed AS s from tournament ORDER BY r, s
- select college, region, seed from tournament ORDER BY 2, 3;
- select college, region, seed from tournament ORDER BY region, seed
- 내림차순으로 정렬하기 위해서는 DESC 키워드를 사용하다. 오름차순으로 정렬하기 위해서는 ASC 키워드를 사용하는데 디폴트로 되어 있으므로 생략이 가능하다.
- HAVING 절은 select_expression 에 나온 컬럼, 컬럼의 별명 등을 참조 할 수 있다. 이 절은 데이터를 출력하기 직전에 가장 마지막으로 처리된다. 따라서 HAVING절 내에는 WHERE에서 사용해야 할 컬럼을 쓰면 안된다. 아래 잘못된 예가 있다.
mysql> select col_name from tbl_name HAVING col_name > 0;
다음과 같이 써야만 한다.
mysql> select col_name from tbl_name WHERE col_name > 0;
MySQL 3.22.5 이후 버전에서는 다음과 같이 쓸 수도 있다.
mysql> select user,max(salary) from users group by user HAVING max(salary)>10;
구 버전인 경우에는 대신 다음과 같이 써야 한다:
mysql> select user,max(salary) AS sum from users group by user HAVING sum>10;
LIMIT 절은 SELECT 문에 의해 나타나는 데이터의 개수를 조절할 수 있게 해 준다. LIMIT 는 하나 또는 두개의 인자를 가질 수 있다. 만일 두개의 인자가 사용되면 앞의 인자는 건너뛸 행의 수를 나타낸다. 뒤의 인자는 최대로 가져올 행의 수이다. 인자가 하나만 사용될 경우 첫번째 인자가 0 이라 간주되고 주어진 값 만큼의 행을 가져오게 된다. 다시 말해 LIMIT n 은 LIMIT 0,n. 과 같은 의미이다.
- select * from table LIMIT 5,10; # 6-15 행까지
- mysql> select * from table LIMIT 5; # 처음 5 행
- select * from table LIMIT 5,10; # 6-15 행까지
Where
조건에 맞는 부분만 가져옴
null 값을 찾는 경우 isNull 을 사용해야 한다.
<>, != 은 같지 않다.
Between
특정 범위 사이의 값을 선택
- select * from table where name between 30 and 80
In
특정한값과 같은 것만 선택
select * from table where math(30)
select * from table where column in ( 30, 45, 80)
GROUP BY
그룹별로 검색을 할 때 사용. 그룹함수를 같이 사용해야 한다.
count(), avg(), min(), max(), sum()
Having
Having 절에 조건을 부여 함으로써 그룹을 제한할 수 있다.
group by에서 사용하는 where 라고 생각하면 된다.
- select avg(math), ban from table group by ban having avg(math) > 70
Like
특정 문자열을 찾는데 사용
와일드 카드(%)는 모든을 의미
‘6%’ 6으로 시작하는 모든
- select * from table where jumin like ‘6%’;
Limit
Limit 절은 쿼리 결과 중에 일정 부분만 가져오는데 사용된다.
- select * from table limit 2 # 2개 가져옴
- select * from table limit 2, 2 # 3번째 부터 2개를 가져옴
- select * from table limit 5, 10 # 6번째 부터 10개를 가져옴
-1은 데이터의 마지막을 의미
- select * from table 9, -1 # 10번째부터 마지막까지 가져옴
Alias(별명)
AS를 사용하여 Alias의 사용이 가능. 별명은 컬럼의 다른 이름이며, order by 와 having 절에도 사용 가능함
- select name as wow from table
테이블 명에도 AS 사용 가능. AS를 직접쓰지 않고, 테이블명 오른쪽에 별명을 줄 이름을 적어준다.
- select table.name, table.id from 원본테이블 별명테이블(table)
정렬
- 정렬 시에 1개 이상의 기준으로 정렬할 수 있음
- 컬럼명 대신 컬럼 포지션을 사용 가능, 시작은 1부터
select * from order by 2, 6 desc
- 컬럼명 대신 별명도 사용 가능
- select column as nick from table order by nick desc;
select 데이터를 파일에 저장
SELECT … INTO OUTFILE ‘file_name’ 는 가져온 데이터를 파일에 저장한다, 이때 파일은 서버에 만들어 지며 같은 이름의 파일이 이미 존재해서는 안된다. 또한 사용자는 반드시 file 권한을 가지고 있어야만 한다 .
JOIN
- table_reference, table_reference
- table_reference [CROSS] JOIN table_reference
- table_reference STRAIGHT_JOIN table_reference
- table_reference LEFT [OUTER] JOIN table_reference ON conditional_expr
- table_reference LEFT [OUTER] JOIN table_reference USING (column_list)
- table_reference NATURAL LEFT [OUTER] JOIN table_reference
- { oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr }
마지막의 LEFT OUTER JOIN 구문은 ODBC 호환을 위해존재 한다.
- 테이블 참조는 tbl_name AS alias_name 또는 tbl_name alias_name 과 같은 방식으로 할 수 있다.
mysql> select t1.name, t2.salary from employee AS t1, info AS t2 where t1.name = t2.name;
- ON 조건은 WHERE 절에서 사용되는 내용이 올 수 있다.
- 만일 LEFT JOIN에 의해 오른편 테이블에 조건에 맞는 자료가 없을 때에는 오른펴 테이블의 모든 컬럼이 NULL인 가상의 행으로 처리된다. 이러한 특징을 이용해 하나의 테이블에만 존재하는 자료의 수를 구할 수 있다.
mysql> select table1.* from table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id is NULL; 위의 예는 table1 에 있는 자료 중에 id 값이 table2 에는 존재하지 않는 자료를 모두 가져온다.
- USING column_list 절에서 사용되는 컬럼명은 반드시 양쪽 테이블에 모두 존재해야 한다. 아래 예를 보자:
A LEFT JOIN B USING (C1,C2,C3,…)
이 문장은 다음과 같이 쓸 수도 있다.
A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,…
그 밖에 몇가지 예를 살펴보면 아래와 같다.mysql> select * from table1,table2 where table1.id=table2.id;
mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id;
mysql> select * from table1 LEFT JOIN table2 USING (id);
mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id LEFT JOIN table3 ON table2.id=table3.id;
크로스 조인
조인된 테이블의 모든 통합된 행을 보여준다. 공통되는 행은 필요하지 않는다.
모든 행을 다 가져오기 때문에 크로스 조인은 정규화된 데이터베이스에는 거의 사용되지 않는다. 첫번째 테이블의 행수를 두 번째 테이블의 행수로 곱한 것 만큼의 행을 반환한다.
Equi-Join
2개의 테이블이나 여러 테이블에서 공통적인 column을 연결해서 테이터를 추출하는 것을 equi조인이라 한다.
- select p.os, c.name from orders o, pc p, clients c where p.pid=o.pid and o.pid=1 and o.cid=c.cid;
Non-Equi-Join
한 테이블의 어떤 column도 Join 할 테이블의 한 column에 직접적으로 일치하지 않을 때 사용한다. 조인 조건은 동등(=) 이외의 연산자를 갖는다.
select p.os, o.pid from orders o, pc p where o.pid > p.pid
Left Join
왼쪽 테이블에 있는 모든 레코드들은 먼저 선택되어지고 오른쪽 테이블에 존재하는 레코드들 중에 왼쪽 테이블에 있는 레코드만 선택된다.
- select * from orders left join pc on orders.pic = pc.pid;
Self Join
같은 테이블 내에서 다른 행과 공통되는 값을 가진 행을 찾고 싶을 때 사용한다.
자기 조인은 한 테이블 내에서 일치하는 데이터를 찾는데 유용하다.
- select parent.uniqid, parent.name, child.uniqid, child.name
- from Table_name as parent, Table_name as child
- where parent.uniqid = child.uniqid AND parent.name <> child.name
UNION
union은 2개 이상의 테이블을 결합하여, 1개의 결과를 나타내주는 쿼리이다.
중복된 것은 제거한다. 테이블의 컬럼 데이터형이 일치해야 union이 가능핟.
게시판 테이블에서 Q&A 테이블, 강좌 테이블 등이 따로 나뉘어져 있을 경우, 이 테이블들을 합칠 때 유용하게 사용될 수 있다.
- select * from one union select * from two
INSERT
- INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,…)] VALUES (expression,…),(…)…
- INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,…)] SELECT …
- INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name SET col_name=expression, col_name=expression, …
INSERT 테이블에 새로운 행을 삽입한다.
The INSERT … SELECT 구문은 다른 테이블에서 SELECT 된 데이터를 입력할 때 사용된다. tbl_name 은 행이 삽입될 테이블 명이다. 컬럼명이나 SET 절은 데이터가 삽입될 컬럼을 지정해 준다.
- 만일 INSERT … VALUES 또는 INSERT … SELECT 구문 내에 컬럼이 지정되지 않았다면 모든 컬럼에 각각 해당되는 데이터가 VALUES() 또는 SELECT 문에 의해 제공되어야 한다. 만일 테이블내의 컬럼의 순서를 모를 경우 DESCRIBE tbl_name 을 이용하면 쉽게 알 수 있다.
- expression 부분은 앞서 VALUES 리스트에 나온 값을 이용할 수 있다. 다음 예를 보자.
mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
그러나 다음의 경우는 오류가 발생한다. 반드시 앞쪽에 나온 값만을 참조 할수 있다는 것을 주의하기 바란다.
mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
- 만일LOW_PRIORITY 키워드를 사용하면 다른 모든 사용자가 사용중인 테이블에서 읽기 작업을 끝낼 때까지 INSERT 문의 실행이 지연된다.
- IGNORE 키워드를 사용하면 새로 삽입되는 데이터와 같은 키(PRIMARY 또는 UNIQUE key) 값을 갖는 데이터는 무시되고 그 다음 데이터가 입력된다. 오류 메세지만 발생하지 않을 뿐 데이터는 입력되지 않는다. 만일 IGNORE 를 사용하지 않을 경우에는 INSERT 의 실행이 중단되어 버린다. 이때 mysql_info() 함수를 이용하면 테이블에 얼마나 많은 행이 삽입되었는지 알 수 있다.
- NOT NULL 컬럼에 NULL 이 입력될 경우 무시되고 디폴트 값으로 입력된다.
- 숫자형 컬럼에 사용범위를 벗어나는 값이 입력될 경우 표시 가능한 가장 가까운 수로 변경되어 삽입된다.
- CHAR, VARCHAR, TEXT , BLOB 컬럼에 최대 입력 자리보다 큰 데이터가 들어올 경우 표시 가능한 부분까지만 잘려서 입력된다.
- 날짜 컬럼에 적절하지 못한 값이 입력되면 제로 값(zero value)으로 입력된다.
DELAYED 옵션은 INSERT 문의 실행을 기다릴 수 없는 사용자가 있을 경우에 매우 유용하다. 이 경우 만일 SELECT 문을 사용하는 사용자가 있을 경우 우선권을 주어 먼저 실행시키고 나서 INSERT 문의 실행을 처리 하게 된다. 이것은 ANSI SQL92 에는 없는 MySQL 의 확장 기능이다.
DELAYED 옵션의 또 다른 장점은 많은 사용자들에 의해 INSERT가 일어날 때 이들에 의해 삽입될 데이터를 모아서 한꺼번에 쓰기 작업을 한다는 것이다. 이 경우 각각의 데이터를 삽입할 때 보다 작업 속도가 빠르다.
REPLACE
- REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,…)] VALUES (expression,…)
- REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,…)] SELECT …
- REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name=expression, col_name=expression,…
REPLACE 명령은 INSERT 명령과 유사하게 동작하나 한가지 차이점은 주키나 UNIQUE 인덱스 컬럼에 기존의 값과 같은 행이 입력될 경우 기존의 행을 삭제하고 새로운 행의 입력이 이루어진다.
UPDATE
UPDATE [LOW_PRIORITY] tbl_name SET col_name1=expr1,col_name2=expr2,… WHERE where_definition]
UPDATE 명령은 테이블내의 각 컬럼의 값을 새로운 값으로 갱신한다. SET 구문은 변경될 컬럼과 새로운 값을 지정해 준다. 만일 WHERE 구문이 주어질 경우 조건을 만족시키는 행만 갱신되며 생략되면 모든 행이 갱신된다.
LOW_PRIORITY 옵션이 사용되면 다른 모든 클라이언트가 해당 테이블에 대한 읽기 작업이 끝날 때까지 UPDATE 의 실행이 지연된다.
SET 구문에서 테이블의 컬럼명을 사용할 경우 해당 컬럼에 저장되어 있는 값이 사용된다 아래의 age 컬럼을 현재의 값보다 1만큼 증가 시키는 예이다.
mysql> UPDATE persondata SET age=age+1;
UPDATE 문은 각각의 연산을 왼쪽에서 오른쪽으로 실행한다. 아래의 age 컬럼을 현재 값의 2배 한 후 1만큼 증가 시키는 예이다.
mysql> UPDATE persondata SET age=age*2, age=age+1;
잠깐!: 만일 현재 값과 같은 값으로 갱신한다면 MySQL 이를 무시하고 실행하지 않는다.
CREATE INDEX
CREATE [UNIQUE] INDEX index_name ON tbl_name (col_name[(length]),… )
CREATE INDEX 구문은 MySQL 3.22. 이전버전에서는 아무런 동작도 하지 않는다. 3.22 이후 버전에서는 CREATE INDEX 는 인덱스를 생성하는ALTER TABLE 구문과 같은 역할을 한다.
일 반적으로 모든 인덱스는 CREATE TABLE 구문을 이용해 테이블 생성시에 만들 수 있지만 CREATE INDEX 구문을 이용하면 이미 존재하는 테이블에 인덱스를 추가할 수 있다. 컬럼의 목록을 괄호 안에 (col1,col2,…) 과 같이 열거함으로써 다중 컬럼 인덱스를 만들 수 있다. 이때 생성되는 인덱스 값은 두 컬럼의 조합으로 만들어 진다.
컬럼의 일부만 인덱스로 생성 CHAR 와 VARCHAR 컬럼에서는 col_name(length) 처럼 length를 지정해 줌으로써 컬럼의 일부분만을 사용할 수 있다.
아래의 예를 name 컬럼의 앞부분 10 자리만을 인덱스로 만드는 것을 보여준다.
mysql> CREATE INDEX part_of_name ON customer (name(10));
이 경우 이름 전체를 인덱스로 만드는 것보다 검색속도는 느려지겠지만 많은 디스크 공간을 절약할 수 있고 INSERT 수행 시 속도가 향상된다.
DROP INDEX
DROP INDEX index_name
인덱스를 삭제한다. DROP INDEX 구문은 MySQL 3.22. 이전버전에서는 아무런 동작도 하지 않는다. 3.22 이후 버전에서는 DROP INDEX 는 인덱스를 삭제하는ALTER TABLE 구문과 같은 역할을 한다.
MySQL 기초
네이밍
식별자 | 최대크기 | 허락되는 문자 |
---|---|---|
네이밍 가이드 라인
- 데이터베이스명은 대문자로 시작하는 것이 좋다.
- 테이블명은 관련되게 이름을 붙이는 것이 좋고, 중간에 언더바를 붙이는 것이 좋다.
- 컬럼명도 관련되어 있는 이름을 붙이는 것이 좋고, 중간에 언더바를 붙이는 것이 좋다.
주석
#, /* */
따옴표 넣기
큰 따옴표는 문제가 안되지만 작은 따옴표는 문제가 된다.
- ” or \’
여러컬럼을 기본키로 주는 법
CREATE TABEL Enrolled
(snum CHAR(8) CONSTRAINT fk_sname REFERENCES Studens,
cname VARCHAR2(10) CONSTRAINT fk_name REFERENCES Class);
CREATE UNIQUE INDEX pk_enrolled ON Enrolled (snum, cname) ;
table 을 생성한 후, unique index 를 만드시면 됩니다.
기본키를 잡고자 하는 순서대로 () 안에 쓰시면 되요.