'DB'에 해당되는 글 48건

  1. 2010.12.05 mysql 한글 메뉴얼 (최적화)
  2. 2010.12.05 인덱스 튜닝
  3. 2010.10.27 mysql_insert_id
  4. 2010.10.27 문자 함수(RIGHT, LEFT, SUBSTRING_INDEX, SUBSTRING, UPPER, REVERSE, LTRIM, LENGTH)
  5. 2010.09.06 MySQL 날짜 관련 함수
  6. 2010.07.08 LIKE, BETWEEN, IN
  7. 2010.07.02 [MySql] JOIN 문
  8. 2010.06.29 GROUP BY
  9. 2010.06.28 group by, having, inner join
  10. 2010.06.17 에러 코드 모음

mysql 한글 메뉴얼 (최적화)

DB 2010. 12. 5. 11:42
http://www.mysqlkorea.co.kr/sub.html?mcode=develop&scode=01&m_no=21436&cat1=7&cat2=0&cat3=0&lang=k

'DB' 카테고리의 다른 글

mssql 천단위 콤마 처리  (0) 2013.01.08
MSSQL 날짜관련 함수  (0) 2012.12.11
iBATIS 강좌 <1> Complex Type Property 사용하기  (0) 2012.11.13
TP-Monitor  (0) 2011.09.09
인덱스 튜닝  (0) 2010.12.05
:

인덱스 튜닝

DB 2010. 12. 5. 11:08
  1. 조화 조건이 걸리는데마다 인덱스를 건다고 전부 타는것이 아니다. 각 조인방식을 참고하도록 하자.

    1. 인덱스를 어떻게 타는지는 원리를 알고 약간의 훈련과 논리적인 생각으로 대충 알 수 있다.
    2. 대부분 개발자가 접하는 SQL최적화는 인덱스에서 결정난다.
    3. 경고!!

      1. 성급하게 인덱싱을 예상하고, 이 작업에 시간을 투자하지 말것. 아래 많이 써놨지만 실제 돌아가는 어플은 아주 쉽게 작업 가능하다.
      2. 인덱싱이나 튜닝 같은거 보다 DB설계와 어플리케이션 매핑이 훨~씬 더 중요하다.

        1. 별거 아닌 튜닝 / 인덱싱질로 시간낭비하지 말것!
        2. 인덱스 추가로 얻는 속도가 크지 않다면 유지보수성을 위해 최소한의 인덱스만 가지는것이 더 좋다.
        3. DB의 메모리와 CPU값이 인건비보다는 싸다는것을 항상 염두하자.
      3. 추가한 인덱스 때문에 전반적인 DB성능 저하 또는 기존 잘 작동하던 SQL이 느려지는 현상이 있을 수 있다.
  2. 기본지식

    1.  인덱스 컬럼은 짧을 수록 좋다. 특히 PK나 코드성 데이터를 적절히 맞춰주자.
    2. 인덱스가 많으면 옵티마이저가 최적의 인덱스를 고르지 못할 수 있으며 변경시 많은 부하를 일으킨다.
    3. 대용량의 데이터에서 랜덤억세스 할 경우 인덱스의 손익분기점(일반적으로 15%)가 훨씬 떨어진다.

      1. 대용량에서 인덱스로 억세스를 할 경우 하드디스크의 암이 움직여야 하는 비용이 상대적으로 크다.
      2. 따라서 인덱스를 걸 경우 아주 적은 자료를 필터링할 수 있게 세심하게 전략을 짜야한다.
    4. 클러스터링 팩터(유사한 로우들이 밀집된 정도)가 액세스 효율에 많은 영향을 미친다.
    5. 인덱스를 걸기 전에 억세스 형태 및 빈도/분포도/중요도를 먼저 수집해야 한다.

      1. 빈도가 높고 중요할수록 / '='로 조인될수록 / 분포가 넓을수록 인덱싱에 유리하다.
      2. ex) =로 필터되것이 1순위, between으로 검색되는것이 2순위 등등
    6. 간혹 인덱스만 검색해도 되는 SQL을 만들겠다고 인덱스를 추가할 수 있다. -> 금지!

      1. 별도의 최적화가 가능하더라도 기존 인덱스를 사용할 수 있는 방향으로 가는것이 좋을때도 있다.
    7. 인덱스만 검색해도 order by가 되도록 만들겠다고 인덱스를 추가할 수 있다. -> 최적화에 따라 신중히 고려

      1. 인덱스 만들때 인덱스의 순서(desc등)도 중요하다. (힌트로 약간의 조정은 가능)
      2. 특정 인덱스를 태울수만 있다면 자동 정렬의 효과를 볼 수 있다.

        1. 정렬 인덱스 구성법칙 : 점조건 +  점조건 + ... + 1번 order by컬럼 + 2번 order by컬럼 + ... + 선분(between)조건
        2. 선분 조건 사용시 group by비용과 랜덤억세스 비용간에 선택을 해야한다. 정답은 데이터 양에따라 그때그때 다르다.

          1. 즉 group by 컬럼이 먼저 들어가면 뒤의 조건들은 인덱스를 타지 못한다. 반대인 경우 인덱스는 타지만 따로 group by해야 한다.
      3. 이러한 방법은 SQL이 의도한 인덱스를 반드시 탄다고 할 수 없음으로 매우 불안하고 신중히 고려해야 하는 방법이다.

        1. 이 방법은 조인 시에도 동일하게 적용된다. 단지 조인방법에 따라 차이가 날 뿐이다.
  3. 복합(결합)인덱스를 타는 조건 (left most prefix)

    1. A+B+C+D로 구성된 복합 인덱스를 가정시 첫번때 인자가 있다면 인덱스를  탄다.

      1. 결합인덱스에서 첫번째 컬럼은 조직의 팀장과도 같다.
      2. 가장 자주 사용되며 카디널리티가 높고 '=' 조건으로 많이 사용되는것을 1st로 골라야 한다.

        1. 추가로 분포도가 좋아야 하며 정렬 순서로 지목되는 컬럼이어야 한다.
      3. 만약 위의 인덱스에서  A+B+D로 조회하는 건이 매우 많다면 따로 인덱스를 추가하는게 더 낫다.
    2. ex) where A and B and C and D  또는   where A and C

    3. 인덱스 스킵 스캔 (Index Skip Scan)

      1. 위의 예제에서 선행 인자가 없이 B,C로만 조건이 주어졌을 경우 A를 강제로 추가해서 인덱스를 타게 만드는 방식.

      2. ex) 위의 A가 낮은 카디널리타(1,2밖에 들어갈 수 없음)일때 a=1 ~~ union all  a=2  ~~ 이런 조건이 추가된다.

  4. 조인시 인덱스 사용 / 자동정렬

    1. Nested Loops

      1. 드라이빙 테이블은 조회조건으로 집합 구성 => 이 집합으로  이너 테이블이 조인키+조회조건의 인덱스를 탄다.

      2. 두 테이블에 적용되는 인덱스에 따라 데이터는 자동 정렬된다.

    2. Hash 조인

      1. 빌드 테이블은 조회조건으로 해시 테이블 구성

      2. 프로브 테이블도 조회조건으로 집합을 만든 후 이것으로 해시를 참조해서 결과 구성

        1. 결국 결과 정렬은 자동으로 프로브 테이블의 인덱스에 맞추어짐.

    3. Sort Merge 조인

      1. 인덱스로 정렬을 자동화하는건 불가능 하다. 당 선행테이블의 소트를 없앨수는 있다.

    4. 복합 인덱스 : 조인시 인덱스를 타게 하기 위해 함수기반 인덱스 등으로 최적화된 인덱스를 꾸릴 수 있다.

      1. 이 방법으로 복잡한 조인관계의 페이징처리에서 group by절을 삭제해 성능향상을 가져올 수 있게된다.

  5. 인덱싱 전략

    1. 인덱스의 수를 줄이는것이 중요하다. 결합 인덱스로 인덱스의 수는 줄일 수 있지만 선행컬럼이 사용되지 않으면 쓸 수 없다.

      1. 따라서 모든 조회조건들을 살펴본후 최대한 중첩되도록 종합적으로 인덱스를 설정해야 한다.
    2. 인덱스를 타도록 만드는것도 중요하지만 자주/많이 사용되는 SQL중심으로 구성해야 한다.

      1. 거의 사용되지 않는 문장을 위해 인덱스를 추가한다면 어느쪽이 이득인지 투자가치를 따져봐야 한다.
    3. 예측하는데 힘쓰지 마라. (특히 SI사업시)

      1. 분포도 같은건 다 만들고 나중에 생각하라. 인덱스는 언제나 추가/수정 가능하다.
  6. 인덱스 종류

    1. 정렬에 따라

      1. Clustered Index : 범위 처리에 유리

      2. Non-Clustered Index : 여러개를 생성할 수 있기에 point처리에 유리

      3. 키값에 Clustered Index를 사용하면 I/O가 몰리면서 병목현상(Hot Spot Problem)이 일어날 수 있다. 주의

    2. 구조에 따라.

      1. 일반 Tree인덱스 : 디폴트

      2. 역 인덱스. => 최근 데이타가 많이 읽히는 곳 

      3. 비트맵 인덱스

        1. 캐 많은 데이터가 있고 분포가 좋지 않으며 수정의 거의 일어나지 않는 테이블

        2. DW처럼 카디널리티가 낮고 다수의 대맨전들이 다양한 구조로 결합해야 하는 경우 (B-Tree인덱스로는 매우 낮은 효울)

        3. 데이터의 수정이 일어날 경우 비트맵을 재생성해야하는 부하 발생

        4. 오라클 9i부터 비트맵 조인 인덱스 기능 제공.       

  7. 인덱스 추가하기

    1.  FK에 인덱스가 모두 걸려있는지 확인.

    2. Uniq값이 들어가야 하는 곳은(사업자 등록번호 등) 반드시 uniq(index)를 설정한다.
    3. 만들어진 모든 인덱스가 사용되는게 아니다. 자주 사용되는 패턴을 참조하여 (복합)인덱스 추가(링크참조)하자.

'DB' 카테고리의 다른 글

mssql 천단위 콤마 처리  (0) 2013.01.08
MSSQL 날짜관련 함수  (0) 2012.12.11
iBATIS 강좌 <1> Complex Type Property 사용하기  (0) 2012.11.13
TP-Monitor  (0) 2011.09.09
mysql 한글 메뉴얼 (최적화)  (0) 2010.12.05
:

mysql_insert_id

DB/MySQL 2010. 10. 27. 11:20

mysql_insert_id

(PHP 3, PHP 4, PHP 5)

mysql_insert_id -- 이전의 INSERT 작업으로부터 생성된 ID를 반환

설명

int mysql_insert_id ( [resource link_identifier] )

이전의 INSERT 질의로부터 AUTO_INCREMENT 컬럼에 의해 생성된 ID를 반환한다.

인수 목록

link_identifier

The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() was called with no arguments. If by chance no connection is found or established, an E_WARNING level warning is generated.

반환값

성공하면 이전의 INSERT 질의에 의한 AUTO_INCREMENT 컬럼으로부터 생성된 ID를, 이전 질의로부터 AUTO_INCREMENT 값이 생성되지 않았다면, 0을, MySQL 접속이 되지 않은 상태였다면 FALSE를 반환한다.

예제

예 1. mysql_insert_id() 예제

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');

mysql_query("INSERT INTO mytable (product) values ('kossu')");
printf("Last inserted record has id %d\n", mysql_insert_id());
?>

Notes

경고

mysql_insert_id()는 원시(native) MySQL C API 함수인 mysql_insert_id()long형태의 반환값을 PHP의 int로 변환한다. AUTO_INCREMENT 컬럼이 BIGINT이면, mysql_insert_id()에 의해 반환되는 값은 잘못될 것이다. 이경우, MySQL SQL 내부 함수인 LAST_INSERT_ID()를 사용하면 된다.

참고: mysql_insert_id()는 최근 수행한 질의에 대해서 동작하기 때문에, 생성된 값은 질의 직후에 mysql_insert_id()를 호출해야 된다.

참고: MySQL SQL 함수인 LAST_INSERT_ID()는 가장 최근에 생성된 AUTO_INCREMENT 값을 담고 있으며, 질의 간에 지워지지는 않는다. 

[출처] mysql_insert_id|작성자 kdepirate

'DB > MySQL' 카테고리의 다른 글

MSSQL PROC ARRAY  (0) 2012.12.11
MySQL 프로세스 리스트 보기  (0) 2011.04.22
문자 함수(RIGHT, LEFT, SUBSTRING_INDEX, SUBSTRING, UPPER, REVERSE, LTRIM, LENGTH)  (0) 2010.10.27
MySQL 날짜 관련 함수  (0) 2010.09.06
LIKE, BETWEEN, IN  (0) 2010.07.08
:

문자 함수(RIGHT, LEFT, SUBSTRING_INDEX, SUBSTRING, UPPER, REVERSE, LTRIM, LENGTH)

DB/MySQL 2010. 10. 27. 10:43

문자를 다룰 수 있는 함수 들 몇개를 소개한다. 출처는  헤드퍼스트 sql 고대로 퍼 담는거다.. ㅎㅎ;;

먼저 문자열 타입으로는 VARCHAR, CHAR 가 있다. 이 타입으로 정해진 컬럼에 관련하여 사용하는 함수들이다..

 

정해진 수의 문자 추출 함수 -  RIGHT(), LEFT()

사용법 : RIGHT()

SELECT RIGHT(location, 2) FROM my_contacts;

SELECT LEFT(location, 2) FROM my_contacts;

 

해석 : my_contacts 라는 테이블의  location의 열에 있는 문자열 에서 오른쪽에서부터 2개의 문자 선택을 의미, LEFT() 함수 일 경우 왼쪽에서 부터 2개의 문자 선택을 의미

특정 문자나 문자열 앞의 모든 문자열을 반환 - SUBSTRING_INDEX()

사용법 :

SELECT SUBSTRING_INDEX(location, ',', 1) FROM my_contacts;

 

해석 : my_contacts테이블의 location 열의 문자열 에서 작은 따옴표 안의 문자열을 찾고( 이경우에는 콤마다.) 그 앞의 모든 문자열을 찾는다. 마지막 인자의 숫자 1은 첫번째 콤마를 찾고 그 앞의 모든 것을 반환하라는 뜻이다.

 

SUBSTRING(your_starting, start_position, length)는 start_position에 있는 문자에서부터 시작해서 your_starting의 일부를 반환한다. length는 반환되는 문자열의 길이

사용법 :

SELECT SUBSTRING('San Antonio, TX', 5, 3);

 

UPPER(your_starting)과 LOWER(your_starting)은 문자열 모두를 대문자 혹은 소문자로 각각 변환 한다.

사용법:

SELECT UPPER('Usa');

SELECT LOWER('spaGHEtti');

REVERSE(your_string)은 말 그대로 문자열의 순서를 역순을 만든다.

 사용법:

SELECT REVERSE('spaGHEtti');

 

LTRIM(your_starting)과 RTRIM(your_starting)은 문자열의 앞(왼쪽 부분) 또는 뒤(오른쪽 부분)에 있는 공백 문자들을 제거한 문자열을 반환한다.

사용법:

SELECT LTRIM('  dogfood  ');

SELECT RTRIM('  catfood  ');

LENGTH(your_starting)은 문자열의 문자수를 반환한다.

사용법:

SELECT LENGTH('San Antonio, TX ');

※ 문자 함수는 테이블에 저장되어 있는 데이터를 바꾸지 않는다. 쿼리의 결과로 변경된 문자열을 반환할 뿐이다

'DB > MySQL' 카테고리의 다른 글

MySQL 프로세스 리스트 보기  (0) 2011.04.22
mysql_insert_id  (0) 2010.10.27
MySQL 날짜 관련 함수  (0) 2010.09.06
LIKE, BETWEEN, IN  (0) 2010.07.08
[MySql] JOIN 문  (0) 2010.07.02
:

MySQL 날짜 관련 함수

DB/MySQL 2010. 9. 6. 20:08

MySQL 날짜 관련 함수

- DAYOFWEEK(date) : 해당 날짜의 요일을 숫자로 반환한다. 일요일은 1, 토요일은 7 이다.
- 예 : select DAYOFWEEK('1998-02-03');



- WEEKDAY(date) : 해당 날짜에 대한 요일을 반환한다. 월요일은 0, 일요일은 6 이다.
- 예 : select WEEKDAY('1997-10-04 22:23:00');



- DAYOFYEAR(date) : 해당 날짜의 1월 1일부터의 날수를 반환한다. 결과값은 1에서 366 까지이다.
- 예 : select DAYOFYEAR('1998-02-03');



- YEAR(date) : 해당 날짜의 년을 반환한다.
- 예 : select YEAR('98-02-03');



- MONTH(date) : 해당 날짜의 월을 반환한다.
- 예 : select MONTH('1998-02-03');



- DAYOFMONTH(date) : 해당 날짜의 일을 반환한다. 결과값은 1 에서 31 까지이다.
- 예 : select DAYOFMONTH('1998-02-03');



- HOUR(time) : 해당날짜의 시간을 반환한다. 결과값은 0 에서 23 이다.
- 예 : select HOUR('10:05:03');



- MINUTE(time) : 해당날짜의 분을 반환한다. 결과값은 0 에서 59 이다.
- 예 : select MINUTE('98-02-03 10:05:03');



- SECOND(time) : 해당날짜의 초를 반환한다. 결과값은 0 에서 59 이다.
- 예 : select SECOND('10:05:03');



- DAYNAME(date) : 해당 날짜의 요일 이름을 반환한다. 일요일은 'Sunday' 이다.
- 예 : select DAYNAME("1998-02-05");



- MONTHNAME(date) : 해당 날짜의 월 이름을 반환한다. 2월은 'February' 이다.
- 예 : select MONTHNAME("1998-02-05");



- QUARTER(date) : 해당 날짜의 분기를 반환한다. 결과값은 1 에서 4 이다.



- WEEK(date,first) : 1월 1일부터 해당날가지의 주 수를 반환한다. 주의 시작을 일요일부터 할경우는 두번째 인자를 0, 월요일부터 시작할 경우는 1 을 넣는다. 결과값은 1 에서 52 이다.
- 예 : select WEEK('1998-02-20',1);



- PERIOD_ADD(P,N) : P (형식은 YYMM 또는 YYYYMM 이어야 한다.) 에 N 만큼의 달 수를 더한값을 반환한다. 주의할것은 두번째 인자는 숫자라는 것이다.
- 예 : select PERIOD_ADD(9801,2);



- PERIOD_DIFF(P1,P2) : 두개의 인자 사이의 달 수를 반환한다. 두개의 인자 모두 형식은 YYMM 또는 YYYYMM 이어야 한다.



- DATE_ADD(date,INTERVAL expr type) : 날짜를 더한 날짜를 반환한다.
- DATE_SUB(date,INTERVAL expr type) : 날짜를 뺀 날짜를 반환한다.
- ADDDATE(date,INTERVAL expr type) : DATE_ADD(date,INTERVAL expr type) 와 동일하다.
- SUBDATE(date,INTERVAL expr type) : DATE_SUB(date,INTERVAL expr type) 와 동일하다.
- EXTRACT(type FROM date) : 날짜에서 해당 부분을 추출한다.
- 예 : SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 SECOND);
SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 DAY);
SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL "1:1" MINUTE_SECOND);
SELECT DATE_SUB("1998-01-01 00:00:00", INTERVAL "1 1:1:1" DAY_SECOND);
SELECT DATE_ADD("1998-01-01 00:00:00", INTERVAL "-1 10" DAY_HOUR);
SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
SELECT EXTRACT(YEAR FROM "1999-07-02");
SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
- 참고 : type 에 사용되는 키워드는 SECOND, MINUTE, HOUR, DAY, MONTH, YEAR, MINUTE_SECOND, HOUR_MINUTE, DAY_HOUR, YEAR_MONTH, HOUR_SECOND, DAY_MINUTE, DAY_SECOND 이다.
- 주의 : 계산한 달의 날수가 작을 경우는 해당달의 마지막 날을 반환한다. 예를 들어 select DATE_ADD('1998-01-30', Interval 1 month); 의 경우 1998-02-28 을 반환한다.



- TO_DAYS(date) : 0 년 부터의 날짜수를 반환한다. 이 함수는 1582 이전 날에 대해서는 계산하지 않는다.
- 예 : select TO_DAYS(950501);



- FROM_DAYS(N) : 해당 숫자만큼의 날짜를 반환한다. 이 함수는 1582 이전 날에 대해서는 계산하지 않는다.
- 예 : select FROM_DAYS(729669);



- DATE_FORMAT(date,format) : 날짜를 해당 형식의 문자열로 변환하여 반환한다.
- 예 : select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
select DATE_FORMAT('1997-10-04 22:23:00', '%D %y %a %d %m %b %j');
select DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w');
- 참고 : 형식은 다음과 같다. %M (달 이름), %W (요일 이름), %Y (YYYY 형식의 년도), %y (YY 형식의 년도), %a (요일 이름의 약자), %d (DD 형식의 날짜), %e (D 형식의 날짜), %m (MM 형식의 날짜), %c (M 형식의 날짜), %H (HH 형식의 시간, 24시간 형식), %k (H 형식의 시간, 24시간 형식), %h (HH 형식의 시간, 12시간 형식), %i (MM 형식의 분), %p (AM 또는 PM)



- TIME_FORMAT(time,format) : DATE_FORMAT(date,format) 과 같은 방식으로 사용할수 있으나 날 이상의 것에 대해서는 NULL 이나 0 을 반환한다.



- CURDATE() : 현재날짜를 반환한다. 숫자와 연산을 할경우 숫자로 변환된다. 형식은 'YYYY-MM-DD' 또는 YYYYMMDD 이다.
- 예 : select CURDATE();
select CURDATE() + 0;



- CURTIME() : 현재시간을 반환한다. 숫자와 연산을 할경우 숫자로 변환된다. 형식은 'HH:MM:SS' 또는 HHMMSS 이다.
- 예 : select CURTIME();
select CURTIME() + 0;



- SYSDATE() : 현재날짜시간을 반환한다. 숫자와 연산을 할경우 숫자로 변환된다. 형식은 'YYYY-MM-DD HH:MM:SS' 또는 YYYYMMDDHHMMSS 이다.
- 예 : select NOW();
select NOW() + 0;



- NOW() : SYSDATE() 와 동일하다.



- UNIX_TIMESTAMP() : '1970-01-01 00:00:00' 부터의 초를 반환한다. 인자가 주어질 경우는 해당 날짜에 대한 유닉스 시간을 반환한다.
- 예 : select UNIX_TIMESTAMP();
select UNIX_TIMESTAMP('1997-10-04 22:23:00');



- FROM_UNIXTIME(unix_timestamp) : 유닉스시간에서 날짜 형식으로 변환한다.
- 예 : select FROM_UNIXTIME(875996580);



- FROM_UNIXTIME(unix_timestamp,format) : 유닉스시간을 날짜형식으로 변환하고 DATE_FORMAT(date,format) 에서 설명한 포맷으로 변환하여 반환한다.
- 예 : select FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x');



- TIME_TO_SEC(time) : 해당 시간의 0:0:0 에서부터의 초를 반환한다.
- 예 : select TIME_TO_SEC('22:23:00');



- SEC_TO_TIME(seconds) : 초를 시간으로 바꾼다.
- 예 : select SEC_TO_TIME(2378);


-출처 : http://www.happycgi.com/

'DB > MySQL' 카테고리의 다른 글

mysql_insert_id  (0) 2010.10.27
문자 함수(RIGHT, LEFT, SUBSTRING_INDEX, SUBSTRING, UPPER, REVERSE, LTRIM, LENGTH)  (0) 2010.10.27
LIKE, BETWEEN, IN  (0) 2010.07.08
[MySql] JOIN 문  (0) 2010.07.02
GROUP BY  (0) 2010.06.29
:

LIKE, BETWEEN, IN

DB/MySQL 2010. 7. 8. 18:14

◘  SQL 입문(3) - 자료검색(2) : 특수 비교 연산자와 검색 결과의 정렬

 

 

▮ LIKE 연산자


 : table의 값과 일부만 일치되는 레코드를 검색하도록 하는 연산자

 

경%

 ‘경’으로 시작하는 모든 문자열. ‘경’ 한글자 포함.

 ex) 경제, 경영...

%과

 ‘과’로 끝나는 모든 문자열. ‘과’ 한글자 포함.

 ex) 화학과, 경제학과...

%김%

 ‘김’이라는 문자가 들어간 모든 문자열

 ex) 김씨, 돌김...

화_

 ‘화’로 끝나는 두글자 단어

 ex) 화학, 화약...

___화

 ‘화’로 끝나는 세글자 단어

 ex) 해당화, 무궁화

_동_

 ‘동’이 가운데 들어간 세글자 단어

 ex) 전동차, 원동기...

 

'_'은 한글이나 영문이나 모두 1글자를 나타낸다. (byte단위가 아님)

    - select sname, major from student where sname like '마%‘;

    => 성이 마씨인 학생의 이름과 전공을 출력

    - select sname, major from student where (sname like '허%‘) and avr <= 1.0;

    => 허씨 성을 가진 학생 중에 학점이 1.0 이하인 학생의 이름과 전공을 출력

 

 

▮ 이외 연산자 : between, in


 - between ~and : 특정 범위 내의 값을 찾고자 할 때

    ex) 학점이 2.0~3.0 사이의 학생을 출력 : select sname from where avr between 2.0 and 3.0;


 - in : 여러 식 중에 하나 이상 일치하는 것을 찾을 때

   ex) 화학,물리학과 학생의 이름 출력 : select sname from student where major in('화학‘,’생물‘);

 

※ 문자열 비교 연산자는 상당수가 Full table scan을 수행하기 때문에 DB가 클 경우 좋지 않다.

'DB > MySQL' 카테고리의 다른 글

문자 함수(RIGHT, LEFT, SUBSTRING_INDEX, SUBSTRING, UPPER, REVERSE, LTRIM, LENGTH)  (0) 2010.10.27
MySQL 날짜 관련 함수  (0) 2010.09.06
[MySql] JOIN 문  (0) 2010.07.02
GROUP BY  (0) 2010.06.29
group by, having, inner join  (0) 2010.06.28
:

[MySql] JOIN 문

DB/MySQL 2010. 7. 2. 15:18
[MySql] JOIN 문

【형식】

table_reference, table_reference

table_reference [CROSS] JOIN table_reference

table_reference INNER JOIN table_reference join_condition

table_reference STRAIGHT_JOIN table_reference

table_reference LEFT [OUTER] JOIN table_reference join_condition

table_reference LEFT [OUTER] JOIN table_reference

table_reference NATURAL [LEFT [OUTER]] JOIN table_reference

{ OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr }

table_reference RIGHT [OUTER] JOIN table_reference join_condition

table_reference RIGHT [OUTER] JOIN table_reference

table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference



여기서

table_reference는 다음과 같이 정의된다.

table_name [[AS] alias] [USE INDEX (key_list)] [IGNORE INDEX (key_list)]

또한 join_condition의 정의는 다음과 같다.

    ON conditional_expr |

    USING (column_list)



 · 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에서 ON이나 USING 부분으로  오른쪽 테이블과 일치하는 레코드가 없으면,

    오른쪽 테이블의 모든 컬럼이 담긴 row에 NULL을 넣는다. 그러므로 다른 테이블에서 카

    운터파트가 없는 레코드를 찾는데 쓰인다.


        mysql> SELECT table1.* FROM table1

             ->        LEFT JOIN table2 ON table1.id=table2.id

             ->        WHERE table2.id IS NULL;


 · 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,...


 · 두 테이블의 NATURAL  [LEFT] JOIN는 INNER  JOIN 또는 USING  절을 사용한 LEFT

    JOIN과 같은 의미이다.

 · INNER JOIN이나 ,(comma)는 같은 의미이다.

 · RIGHT JOIN는 LEFT JOIN과 유사하다.

 · STRAIGHT_JOIN은 JOIN과 같지만, 왼쪽 테이블을 오른쪽 테이블보다 먼저 읽히는 점

    이 다르다.

 · USE INDEX (key_list)를 사용하면, 여러 인덱스 중에서 오직  하나의 인덱스를 지정하

    는 것이고, IGNORE INDEX (key_list)는 지정한 인덱스를 사용하지 않게 한다. FORCE

    INDEX는 USE INDEX (key_list)와 같지만, 테이블 스캔기능이 더 있다.

     USE/IGNORE KEY와 USE/IGNORE INDEX는 동일한 의미이다.


예를 들어,

        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;

        mysql> SELECT * FROM table1 USE INDEX (key1,key2)

            ->         WHERE key1=1 AND key2=2 AND key3=3;

        mysql> SELECT * FROM table1 IGNORE INDEX (key3)

            ->         WHERE key1=1 AND key2=2 AND key3=3;




JOIN 문


둘 이상의 테이블의 레코드 조합으로 하나의 테이블 레코드인 것처럼  찾는 것을 join이라

한다. 이해를 돕기 위하여 다음 테이블을 가정한다.


mysql> select * from test1;

+--------+------+

| a      | b    |

+--------+------+

| 금강   |    1 |

| 한강   |    2 |

| 대동강 |    3 |

| 두만강 |    4 |

+--------+------+

4 rows in set (0.00 sec)


mysql> select * from test2;

+------+--------+

| b    | d      |

+------+--------+

|    1 | 백두산 |

|    2 | 금강산 |

|    5 | 지리산 |

|    6 | 한라산 |

+------+--------+

4 rows in set (0.00 sec)


mysql>


1) FULL JOIN

FULL JOIN은 각 테이블의 레코드 수를 곱한 만큼의 레코드를 출력하며 이를 Cartesian

product라 한다.

from test1, test2에서 사용한 컴마(,)를 join 연산자로 생각하면 된다.

컴마 대신 join이나 cross join을 사용해도 같은 결과를 보인다.

【예제】

mysql> select * from test1,test2;

+--------+------+------+--------+

| a      | b    | b    | d      |

+--------+------+------+--------+

| 금강   |    1 |    1 | 백두산 |

| 한강   |    2 |    1 | 백두산 |

| 대동강 |    3 |    1 | 백두산 |

| 두만강 |    4 |    1 | 백두산 |

| 금강   |    1 |    2 | 금강산 |

| 한강   |    2 |    2 | 금강산 |

| 대동강 |    3 |    2 | 금강산 |

| 두만강 |    4 |    2 | 금강산 |

| 금강   |    1 |    5 | 지리산 |

| 한강   |    2 |    5 | 지리산 |

| 대동강 |    3 |    5 | 지리산 |

| 두만강 |    4 |    5 | 지리산 |

| 금강   |    1 |    6 | 한라산 |

| 한강   |    2 |    6 | 한라산 |

| 대동강 |    3 |    6 | 한라산 |

| 두만강 |    4 |    6 | 한라산 |

+--------+------+------+--------+

16 rows in set (0.00 sec)


mysql> select * from test1 join test2;


mysql> select * from test1 cross join test2;


mysql>


2) STRAIGHT_JOIN

 straight_join은 컬럼의 순서를 from 절에 나오는 테이블의 순서대로 출력하는 join이다.

【예제】

mysql> select * from test1,test2;


mysql> select * from test2,test1;


mysql> select * from test1 straight_join test2;


mysql> select * from test2 straight_join test1;

+------+--------+--------+------+

| b    | d      | a      | b    |

+------+--------+--------+------+

|    1 | 백두산 | 금강   |    1 |

|    2 | 금강산 | 금강   |    1 |

|    5 | 지리산 | 금강   |    1 |

|    6 | 한라산 | 금강   |    1 |

|    1 | 백두산 | 한강   |    2 |

|    2 | 금강산 | 한강   |    2 |

|    5 | 지리산 | 한강   |    2 |

|    6 | 한라산 | 한강   |    2 |

|    1 | 백두산 | 대동강 |    3 |

|    2 | 금강산 | 대동강 |    3 |

|    5 | 지리산 | 대동강 |    3 |

|    6 | 한라산 | 대동강 |    3 |

|    1 | 백두산 | 두만강 |    4 |

|    2 | 금강산 | 두만강 |    4 |

|    5 | 지리산 | 두만강 |    4 |

|    6 | 한라산 | 두만강 |    4 |

+------+--------+--------+------+

16 rows in set (0.01 sec)


mysql>


3) Theta JOIN

 full join에 where 절로 조건을 제시할 경우 이를 Theta join이라 한다.

예를 들어, test1과 test2에 b의 값이 동일한 레코드를 선택하는 경우는 다음과 같다.

【예제】

mysql> select * from test1, test2 where test1.b=test2.b;

+------+------+------+--------+

| a    | b    | b    | d      |

+------+------+------+--------+

| 금강 |    1 |    1 | 백두산 |

| 한강 |    2 |    2 | 금강산 |

+------+------+------+--------+

2 rows in set (0.00 sec)


mysql>


4) INNER JOIN

Inner join를 이용하여 앞 예제와 동일한 결과를 얻을 수 있는 예는 다음과 같다. 

이는 select 문에서 join에 사용할 컬럼명을 ON test1.b=test2.b와 같이 직접 지정해도 된다.

【예제】

mysql> select * from test1 inner join test2 using(b);

+------+------+------+--------+

| a    | b    | b    | d      |

+------+------+------+--------+

| 금강 |    1 |    1 | 백두산 |

| 한강 |    2 |    2 | 금강산 |

+------+------+------+--------+

2 rows in set (0.00 sec)


mysql> select * from test1 inner join test2 on test1.b=test2.b;

+------+------+------+--------+

| a    | b    | b    | d      |

+------+------+------+--------+

| 금강 |    1 |    1 | 백두산 |

| 한강 |    2 |    2 | 금강산 |

+------+------+------+--------+

2 rows in set (0.00 sec)


mysql> select * from test1, test2 where test1.b=test2.b;


mysql>


5) NATURAL JOIN

두 테이블에 같은 이름을 가진 컬럼이 있고, 이 컬럼을 기준으로 join을 하려면 natural join

을 사용한다.

【예제】

mysql> select * from test1 natural join test2;

+------+------+------+--------+

| a    | b    | b    | d      |

+------+------+------+--------+

| 금강 |    1 |    1 | 백두산 |

| 한강 |    2 |    2 | 금강산 |

+------+------+------+--------+

2 rows in set (0.00 sec)


mysql>


6) LEFT OUTER JOIN

test1에는 4개의 레코드가 있는데 where test1.b=test2.b라는 조건 때문에 두 개의 레코드 밖

에 선택되지 않았다. 이때 test2의 b에 test1의 b 값이 존재하지  않더라도 test1의 레코드를

모두 가져오려면 left outer join을 사용한다. left outer join에서 outer는 옵션이므로  생략해

도 된다.

【예제】

mysql> select * from test1 left join test2 using(b);

+--------+------+------+--------+

| a      | b    | b    | d      |

+--------+------+------+--------+

| 금강   |    1 |    1 | 백두산 |

| 한강   |    2 |    2 | 금강산 |

| 대동강 |    3 | NULL | NULL   |

| 두만강 |    4 | NULL | NULL   |

+--------+------+------+--------+

4 rows in set (0.00 sec)


mysql> select * from test1 left join test2 on test1.b=test2.b;

+--------+------+------+--------+

| a      | b    | b    | d      |

+--------+------+------+--------+

| 금강   |    1 |    1 | 백두산 |

| 한강   |    2 |    2 | 금강산 |

| 대동강 |    3 | NULL | NULL   |

| 두만강 |    4 | NULL | NULL   |

+--------+------+------+--------+

4 rows in set (0.01 sec)


mysql>


7) RIGHT OUTER JOIN

 test2에는 4개의 레코드가 있는데, where test1.b=test2.b라는 조건 때문에 2개의 레코드 밖

에 선택되지 않는다. 이때 test1의  b에 test2의 b값이 존재하지 않더라도  test2의 레코드를

모두 가져오려면 right outer join을 사용한다. right outer join에서 outer는 옵션이므로 생략

할 수 있다.

【예제】

mysql> select * from test1 right join test2 on test1.b=test2.b;

+------+------+------+--------+

| a    | b    | b    | d      |

+------+------+------+--------+

| 금강 |    1 |    1 | 백두산 |

| 한강 |    2 |    2 | 금강산 |

| NULL | NULL |    5 | 지리산 |

| NULL | NULL |    6 | 한라산 |

+------+------+------+--------+

4 rows in set (0.00 sec)


mysql>


출처 - http://blog.naver.com/tyboss?Redirect=Log&logNo=70008713640

'DB > MySQL' 카테고리의 다른 글

MySQL 날짜 관련 함수  (0) 2010.09.06
LIKE, BETWEEN, IN  (0) 2010.07.08
GROUP BY  (0) 2010.06.29
group by, having, inner join  (0) 2010.06.28
에러 코드 모음  (0) 2010.06.17
:

GROUP BY

DB/MySQL 2010. 6. 29. 13:37

GROUP BY 절은 내가 하고 있는 업무에서 자주 쓰게 되는
문법이다.
제대로 쓰려면, 조금씩 연구를 해야하는 법!

지금부터 GROUP BY에 대해 알아보자.

그리고,
GROUP BY 와 함께 사용하는
HAVING은 무엇이고, 어떠한 시점으로 작동하는 지 살펴보도록 하자.


**** [ SAMPLE CODE ] *****************************************

mysql> select * from A
+------+--------+--------+
| id   | value1 | value2 |
+------+--------+--------+
|    1 |     10 | kkk    |
|    2 |     30 | mmm    |
|    3 |     20 | hhh    |
|    4 |     10 | jjj    |
|    5 |     30 | kkk    |
|    6 |     10 | kkk    |
+------+--------+--------+
6 rows in set (0.00 sec)

설명을 위해 임시로 테이블 a를 생성하여,
GROUP BY 값을 볼 수 있도록,
중복된 값을 넣어보았다.

======================================================

mysql> SELECT *
    -> FROM A a
    -> GROUP BY a.value1, a.value2;
+------+--------+--------+
| id   | value1 | value2 |
+------+--------+--------+
|    4 |     10 | jjj    |
|    1 |     10 | kkk    |
|    3 |     20 | hhh    |
|    5 |     30 | kkk    |
|    2 |     30 | mmm    |
+------+--------+--------+
5 rows in set (0.00 sec)

단순히 HAVING절의 삽입없이,
GROUP BY를 사용한 경우이다.
이 예에서 볼 수 있듯이,
GROUP BY는 내부적인 정렬(sorting)이 이루어지며,
중복된 값을 배제한다.

======================================================


mysql> SELECT *
    -> FROM A a
    -> GROUP BY a.value1, a.value2
    -> HAVING count(*) > 1
    -> ;
+------+--------+--------+
| id   | value1 | value2 |
+------+--------+--------+
|    1 |     10 | kkk    |
+------+--------+--------+
1 row in set (0.01 sec)

HAVING은 GROUP BY에 부여하는 조건을 명시한다.


위의 예는 HAVING을 사용하여 중복된 ROW를 찾는 예이다.

그런데 여기서 의문점이 제기된다. 
'도대체 HAVING이 적용되는 시점은 언제일까?'

테이블 A에서 count(*)>1 인 녀석을 먼저 찾고 GROUP BY가 적용될까?
아니면, GROUP BY를 먼저 적용하고 난 결과물 중 count(*)>1 인 녀석을 찾는 것일까?

단순히 위의 결과로만 본다면, 어느 것이 먼저 적용되는 지 알기 힘들다.

****************************************************************

골머리 싸잡고 혼자 고민하다,
결국 내가 아는 고수분의 도움을 얻어,
내부적으로 발생하는 순서를 알아내었다.

**** [ HAVING의 타이밍 ] *****************************************

+------+--------+--------+
value1           | value2    |  row_number 
━┳━ 
10  ━┳━ jjj ━┳━━ 4     
   ┃            ┃
   ┃            ┗━ 
kkk  ┳━━ 
1
   ┃                         ┃
   ┃                         ┗━━ 
6
   ┃
   ┣━ 
20  ━━━ hhh ━━━ 
3
   ┃
   ┃
   ┗━ 
30  ━┳━ kkk   ━━━ 
5
                  ┃
                  ┗━ 
mmm ━━━ 2

(젠장 그리기 빡세네 --;;)
GROUP BY 가 value1, value2  순서로 수행되면,
위와 같은 트리가 만들어진다.

그렇다면? 
눈치 빠른 사람은 이미 알아챘겠지만,
HAVING의 타이밍이 이것에 달려 있다는 것이다.

즉,
트리의 LEAF(위 그림중 row_number라고 되어 있는 영역) 영역이
HAVING이 계산되는 시점이다.
각각의 분류가 완료되고 난 후,
각 카테고리 별로 HAVING의 조건이 검색된다.


자, 그럼 이제부터는 어느 시점에서 조건이 발효되는 지 
알테니,
잘 써먹도록 하자. (^0^)/
******************************

출처 -  http://blog.naver.com/nadarim?Redirect=Log&logNo=70047337113

'DB > MySQL' 카테고리의 다른 글

LIKE, BETWEEN, IN  (0) 2010.07.08
[MySql] JOIN 문  (0) 2010.07.02
group by, having, inner join  (0) 2010.06.28
에러 코드 모음  (0) 2010.06.17
mysql 접속 여부 확인 및 에러  (0) 2010.05.31
:

group by, having, inner join

DB/MySQL 2010. 6. 28. 15:06

* group by..

 

group by절은 그룹별로 검색을 하게 해 준다. 특정 필드에 대해 중복이 되지 않도록

그루핑이 가능하다.

 

id 1111 school 백수초딩학교

id 1111 school 백마고등학교

id 2222 school 응가초딩학교

id 2222 school 응가대학교

 

이럴때 id로만 그루핑해서 몇명이 있는지 보고 싶을 때 group by id 를 사용한다.

group by 절을 사용할 때는 그룹 함수를 같이 사용해야 하는데, 대표적인 그룹함수에는

COUNT(), AVG(), MIN(), MAX(), SUM()이 있다.

 

* having

 

having 구문은 group by를 사용할때 연이어서 조건문 사용을 가능하게 해준다.

 

예)

 

SELECT id, COUNT(*) FROM member WHERE cc='Y' GROUP BY id HAVING COUNT(cc)=2;

 

설명:

member table에서 id가 중복되지 않게 group 으로 묶은 후에,

cc 필드의 갯수가 2인 것만 으로 조건 제약.

 

 

 

* inner join..

 

inner join에서의 조건문은 where이 아닌 on을 사용해서 쓴다.

 

예)

SELECT p.id, p.name, p.commnet FROM member AS p
LEFT INNER JOIN member_crazy AS r
ON p.id=r.id
LEFT INNER JOIN member_babo AS c
ON p.id=c.id

'DB > MySQL' 카테고리의 다른 글

[MySql] JOIN 문  (0) 2010.07.02
GROUP BY  (0) 2010.06.29
에러 코드 모음  (0) 2010.06.17
mysql 접속 여부 확인 및 에러  (0) 2010.05.31
mysql_fetch 계열 함수  (0) 2010.05.31
:

에러 코드 모음

DB/MySQL 2010. 6. 17. 18:13

1062 : Duplicate entry '0' for key 1

동일한 값이 들어갈 수 없는 컬럼에 같은 데이터가 들어갈 경우  

idx 컬럼의 auto_increment 속성 확인해 볼것




 

'DB > MySQL' 카테고리의 다른 글

GROUP BY  (0) 2010.06.29
group by, having, inner join  (0) 2010.06.28
mysql 접속 여부 확인 및 에러  (0) 2010.05.31
mysql_fetch 계열 함수  (0) 2010.05.31
php mysql 연동 함수  (0) 2010.05.10
: