블로그 이미지
우디냥
"지금 잠을 자면 꿈을 꾸지만, 지금 공부하면 꿈을 이룰수있다"

calendar

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  

Notice

'─☻раցеº②/└ᘐ mysql'에 해당되는 글 1

  1. 2008.02.15 정보 함수
  • BENCHMARK(count,expr)

BENCHMARK() 함수는 수식 expr count 횟수 만큼 반복 실행한다. 이 함수는 MySQL이 수식을 얼마나 빨리 처리하는지를 계산할 때 사용할 수가 있다. 그 결과 값은 항상 0 이 된다. mysql 클라이언트 내부에서 이 함수를 의도적으로 사용할 수가 있는데, 이것은 쿼리 실행 횟수를 레포트한다:

mysql> SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE('hello','goodbye')) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (4.74 sec)

레포트된 시간은 클라이언트 단에서의 경과 시간이며, 서버단에서의 CPU 경과 시간은 아니다. BENCHMARK() 함수를 여러 번 반복 실행하는 것이 좋으며, 이를 통해서 서버 머신이 얼마나 로드가 걸려 있는지 알 수가 있다.

  • CHARSET(str)

스트링 인수의 문자 셋을 리턴한다.

mysql> SELECT CHARSET('abc');
        -> 'latin1'
mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
        -> 'utf8'
mysql> SELECT CHARSET(USER());
        -> 'utf8'
  • COERCIBILITY(str)

스트링 인수의 콜레션 코에시빌러티 (collation coercibility) 값을 리턴한다.

mysql> SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
        -> 0
mysql> SELECT COERCIBILITY(USER());
        -> 3
mysql> SELECT COERCIBILITY('abc');
        -> 4

리턴되는 값은 아래 테이블에 설명된 의미를 갖는다. 값이 낮을 수로 높은 우선 순위를 갖는다.

 

Coercibility

Meaning

Example

0

Explicit collation

Value with COLLATE clause

1

No collation

Concatenation of strings with different collations

2

Implicit collation

Column value

3

System constant

USER() return value

4

Coercible

Literal string

5

Ignorable

NULL or an expression derived from NULL


MySQL 5.0.3 이전 버전의 경우, 리턴 값은 아래의 의미를 갖고 있었으며, USER() 와 같은 함수는 코에시빌러티가 2가 된다:

 

Coercibility

Meaning

Example

0

Explicit collation

Value with COLLATE clause

1

No collation

Concatenation of strings with different collations

2

Implicit collation

Column value, stored routine parameter or local variable

3

Coercible

Literal string

  • COLLATION(str)

스트링 인수의 콜레션을 리턴한다.

mysql> SELECT COLLATION('abc');
        -> 'latin1_swedish_ci'
mysql> SELECT COLLATION(_utf8'abc');
        -> 'utf8_general_ci'
  • CONNECTION_ID()

커넥션에 대한 커넥션 ID (쓰레드 ID)를 리턴한다. 모든 커넥션은 고유의 ID를 가지게 된다.

mysql> SELECT CONNECTION_ID();
        -> 23786
  • CURRENT_USER, CURRENT_USER()

서버가 현재의 클라이언트를 인증하기 위해 사용한 MySQL 계정에 대한 사용자 이름과 호스트 이름의 조합을 리턴한다. 이 계정은 여러분의 접속 권한을 결정한다. MySQL 5.0.10 버전까지는, SQL SECURITY DEFINER 특성으로 정의된 스토어드 루틴내에서, CURRENT_USER()은 루틴의 생성자 (creator)를 리턴한다. 리턴 값은 utf8 문자 셋에 있는 스트링이 된다.

CURRENT_USER()의 값은 USER()의 리턴 값과는 다르다.

mysql> SELECT USER();
        -> 'davida@localhost'
mysql> SELECT * FROM mysql.user;
ERROR 1044: Access denied for user ''@'localhost' to
database 'mysql'
mysql> SELECT CURRENT_USER();
        -> '@localhost'

위의 예제는, 클라이언트가 davida (USER() 함수가 가리키는 것 처럼)의 사용자 이름을 지정하였더라도, 서버는 익명의 사용자 이름 (CURRENT_USER() 값의 빈 사용자 이름 부분으로 보여지는)을 사용해서 클라이언트를 인증하고 있음을 보여 주는 것이다. 그 이유 중의 하나는 davida에 대한 그랜트 테이블에 아무런 계정 정보도 없기 때문이다.

  • DATABASE()

디폴트 (현재) 데이터 베이스 이름을 utf8 문자 셋의 스트링 형태로 리턴한다. 만일 데폴트 데이터베이스 이름이 존재하지 않는다면, DATABASE()NULL 을 리턴한다. 스토어드 루틴내에서는, 루틴이 연결되어 있는 데이터 베이스가 디폴트 데이터베이스가 되며, 이것이 반드시 호출 문맥 (context)에 있는 디폴트 데이터 베이스가 될 필요는 없다.

mysql> SELECT DATABASE();
        -> 'test'
  • FOUND_ROWS()

SELECT 명령문은 서버가 클라이언트에게 리턴하는 열의 숫자를 제한하기 위한 LIMIT 구문을 포함할 수도 있다. 어떤 경우에는, LIMIT 구문 없이 얼마나 많은 수의 열이 리턴되는지 알고 있는 것이 바람직하다. 이렇게 열의 숫자를 세기 위해서는, SELECT 명령문 안에 SQL_CALC_FOUND_ROWS 옵션을 추가하고, 나중에 FOUND_ROWS() 함수를 선언한다:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

두 번째 SELECTLIMIT 구문이 없이 작성된 첫 번째 SELECT가 얼마나 많은 열을 리턴했는지를 나타내는 숫자를 리턴한다. (만일 이전 SELECT 명령문에 SQL_CALC_FOUND_ROWS 옵션이 포함되어 있지 않다면, FOUND_ROWS()LIMIT가 사용되었을 경우와는 다른 결과를 리턴한다.)

 

FOUND_ROWS()를 통해서 셀 수 있는 열은 의미가 없으며, SELECT SQL_CALC_FOUND_ROWS 명령문 다음에 나오는 명령문들에도 의미가 없게 된다. 만일 나중에 이 값을 참조하고자 한다면, 우선 저장을 해 둔다:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
mysql> SET @rows = FOUND_ROWS();

만일 여러분이 SELECT SQL_CALC_FOUND_ROWS를 사용한다면, MySQL은 결과 셋 전체에 얼마나 많은 열이 있는지를 계산하게 된다. 하지만, 이렇게 하면 LIMIT 를 사용하지 않고 쿼리를 다시 구동시키는 것 보다 속도가 빨라지게 되는데, 그 이유는 결과 셋을 클라이언트에 전달할 필요가 없기 때문이다.

 

SQL_CALC_FOUND_ROWS FOUND_ROWS()는 쿼리가 리턴하는 열의 수를 제한하고자 할 때 뿐만 아니라, 쿼리를 다시 구동 시키지 않고서 전체 결과 셋에 있는 열의 숫자를 파악하고자 할 때 유용하게 사용할 수가 있는 함수이다. 어떤 검색 결과에 대한 다른 섹션을 보여주는 페이지에 대한 링크를 가지고 있는 페이지 디스플레이를 표현하는 웹 스크립트가 한 가지 예가 된다. FOUND_ROWS()를 사용하면 여러분은 결과 값의 나머지에 대해서 다른 페이지가 얼마나 필요한지를 알아낼 수가 있다.

 

SQL_CALC_FOUND_ROWS FOUND_ROWS()의 사용은 단순한 SELECT 명령문에 대해서 보다 UNION 명령문에 대해서가 훨씬 복잡한데, 그 이유는 LIMITUNION 내의 여러 곳에서 발생할 수가 있기 때문이다. UNION 내의 개별적인 SELECT 명령문에 적용하거나, 또는 전체적으로 UNION 결과에 적용할 수도 있다.

 

UNION 에 대해서 SQL_CALC_FOUND_ROWS를 사용하는 것은, 이것이 글로벌 LIMIT 없이 리턴되는 열 카운트를 리턴하기 때문이다. UNION 과 함께 SQL_CALC_FOUND_ROWS를 사용하는 조건은 다음과 같다:

    • SQL_CALC_FOUND_ROWS 키워드는 반드시 UNION의 맨 처음 SELECT 에 나타나야 한다.
    • FOUND_ROWS()의 값은 UNION ALL 이 사용되는 경우에만 정확하게 된다. 만일 UNION ALL  없이 사용된다면, 중복 제거가 발생하고 FOUND_ROWS()의 값은 추정치가 된다.
    • 만일 LIMIT UNION 내에 나타나면, SQL_CALC_FOUND_ROWS 은 무시가 되고 UNION을 처리하기 위해 생성된 임시 테이블에 있는 열의 숫자가 리턴된다.

 

  • LAST_INSERT_ID(), LAST_INSERT_ID(expr)

가장 최근의 INSERT 또는 UPDATE 명령문에 의해 AUTO_INCREMENT 컬럼용으로 설정된 값 중에 맨 처음으로 자동 생성된 값을 리턴한다.

mysql> SELECT LAST_INSERT_ID();
        -> 195

생성된 ID 는 커넥션 별로 서버에 의해 관리된다. , 이 함수에 의해 주어진 클라이언트에 리턴되는 값은 클라이언트에 의해 AUTO_INCREMENT 컬럼에 영향을 주는 가장 최근의 명령문을 위해 클라이언트가 생성한 맨 처음의 AUTO_INCREMENT 값이 된다. 이 값은 다른 클라이언트에 의해서는 영향을 받지 않게 되는데, 다른 클라이언트가 자신의 고유 AUTO_INCREMENT 값을 생성한다고 하더라도 마찬가지가 된다. 이러한 특성으로 인해 각각의 클라이언트는 다른 클라이언트의 행동에는 상관없이 자신만의 고유 ID를 가질 수 있게 되며, 락 또는 트랜젝션이 필요 없게 되는 것이다.

 

LAST_INSERT_ID()의 값은 여러분이 열의 AUTO_INCREMENT 컬럼을 비-“magic (, NULL 0 이 아닌 값)으로 설정한다면 변경되지 않는다.

 

Important: 만일 여러분이 하나의 INSERT 명령문을이용해서 여러 개의 열을 삽입한다면, LAST_INSERT_ID()은 맨 처음 삽입된 열에 대한 값만을 리턴하게 된다. 이렇게 되는 이유는, 다른 서버들에 대응해서 동일한 INSERT 명령문을 쉽게 재 생성할 수 있도록 하기 위함이다.

예문을 보도록 하자:

mysql> USE test;
Database changed
mysql> CREATE TABLE t (
    ->   id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
    ->   name VARCHAR(10) NOT NULL
    -> );
Query OK, 0 rows affected (0.09 sec)
 
mysql> INSERT INTO t VALUES (NULL, 'Bob');
Query OK, 1 row affected (0.01 sec)
 
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
|  1 | Bob  |
+----+------+
1 row in set (0.01 sec)
 
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+
1 row in set (0.00 sec)
 
mysql> INSERT INTO t VALUES
    -> (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
|  1 | Bob  |
|  2 | Mary |
|  3 | Jane |
|  4 | Lisa |
+----+------+
4 rows in set (0.01 sec)
 
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

비록 두 번째 INSERT 명령문이 3개의 새로운 열을 t 에 삽입하기는 하지만, 이렇게 삽입된 열중의 맨 처음 열을 위해 생성된 ID 2가 되며, 이 값이 뒤따라 나오는 SELECT 명령문을 위해 LAST_INSERT_ID()가 리턴하는 값이 되는 것이다.

 

만일 여러분이 NSERT IGNORE를 사용해서 그 열을 무시한다면, AUTO_INCREMENT 카운터는 증가하지 않게 되고 LAST_INSERT_ID()0 을 리턴하는데, 이것은 아무런 열도 삽입되지 않았다는 것을 의미하는 것이다.

 

만일 expr LAST_INSERT_ID()에 대한 인수 형태로 주어진다면, 그 인수의 값은 함수에 의해 리턴되고 LAST_INSERT_ID()에 의해 리턴되어야 할 다음 값으로 기억된다. 이것은 시퀀스를 시뮬레이트하기 위해 사용될 수가 있다:

 

  • 시퀀스 카운터를 가지고 있기 위한 테이블을 생성하고 초기화 시킨다:
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
  •  아래와 같이 시퀀스 숫자를 생성하기 위해 테이블을 사용한다:
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();

UPDATE 명령문은 시퀀스 카운터를 증가시키고 LAST_INSERT_ID()에 대한 다음 호출이 업데이트된 값을 리턴 하도록 만든다. SELECT 명령문은 그 값을 복구시킨다. mysql_insert_id() C API 함수 역시 이 값을 가져오는데 사용할 수가 있다. Section 22.2.3.36, “mysql_insert_id()를 참조할 것.

 

여러분은 LAST_INSERT_ID()를 호출하지 않고서도 시퀀스를 생성할 수 있지만, 위와 같은 방식으로 이 함수를 사용하는 것이 최종적으로 자동 생성된 값을 서버에서 유지 관리하는데 더 효율적이 된다. 여러 명의 클라이언트가 UPDATE 명령문을 실행해서 SELECT 명령문을 사용해서 자신들의 고유 시퀀스 값을 가져가기 때문에 이러한 방식이 더욱 안전한 것이다.

 

mysql_insert_id()INSERT UPDATE 명령문이 실행된이후에만 업데이트가 된다는 점을 알아두자. 따라서, 여러분은 SELECT 또는 SET과 같은 다른 SQL 명령문을 실행한 후에 LAST_INSERT_ID(expr)에 대한 값을 추출하기 위해 C API 함수를 사용할 수는 없게 된다.

  • ROW_COUNT()

ROW_COUNT()는 이전 명령문에 의해 업데이트, 삽입, 또는 삭제된 열의 숫자를 리턴한다. 이 값은 mysql_affected_rows() C API 함수로부터 얻는 열 카운트 값과 같은 값이 된다.

mysql> INSERT INTO t VALUES(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)
 
mysql> DELETE FROM t WHERE i IN(1,2);
Query OK, 2 rows affected (0.00 sec)
 
mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+
1 row in set (0.00 sec)

ROW_COUNT() MySQL 5.0.1에서 추가되었다.

  • SCHEMA()

이 함수는 DATABASE()과 동일한 것이며, MySQL 5.0.2에서 추가가 되었다.

  • SESSION_USER()

SESSION_USER()USER()과 동일한 함수다.

  • SYSTEM_USER()

SYSTEM_USER()USER()과 동일한 함수다.

  • USER()

현재의 MySQL 사용자 이름과 호스트 이름을 utf8 문자 셋의 스트링 형태로 리턴한다.

mysql> SELECT USER();
        -> 'davida@localhost'

결과 값은 여러분이 서버에 접속을 할 때 지정한 사용자 이름을 가리키게 되며, 여러분이 접속한 클라이언트 호스트가 된다. 이 값은 CURRENT_USER()의 값과 다른 값이다.

여러분은 아래와 같이 사용자 이름만 얻을 수도 있다:

mysql> SELECT SUBSTRING_INDEX(USER(),'@',1);
        -> 'davida'
  • VERSION()

MySQL  서버 버전을 가리키는 스트링을 리턴한다. 스트링은 utf8 문자 셋을 사용한다.

mysql> SELECT VERSION();
        -> '5.0.23-standard'

만일 여러분의 버전 스트링이 -log 로 끝난다면, 이것은 로깅이 현재 활성화 되어 있음을 의미하는 것이다.

  • BENCHMARK(count,expr)

BENCHMARK() 함수는 수식 expr count 횟수 만큼 반복 실행한다. 이 함수는 MySQL이 수식을 얼마나 빨리 처리하는지를 계산할 때 사용할 수가 있다. 그 결과 값은 항상 0 이 된다. mysql 클라이언트 내부에서 이 함수를 의도적으로 사용할 수가 있는데, 이것은 쿼리 실행 횟수를 레포트한다:

mysql> SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE('hello','goodbye')) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (4.74 sec)

레포트된 시간은 클라이언트 단에서의 경과 시간이며, 서버단에서의 CPU 경과 시간은 아니다. BENCHMARK() 함수를 여러 번 반복 실행하는 것이 좋으며, 이를 통해서 서버 머신이 얼마나 로드가 걸려 있는지 알 수가 있다.

  • CHARSET(str)

스트링 인수의 문자 셋을 리턴한다.

mysql> SELECT CHARSET('abc');
        -> 'latin1'
mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
        -> 'utf8'
mysql> SELECT CHARSET(USER());
        -> 'utf8'
  • COERCIBILITY(str)

스트링 인수의 콜레션 코에시빌러티 (collation coercibility) 값을 리턴한다.

mysql> SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
        -> 0
mysql> SELECT COERCIBILITY(USER());
        -> 3
mysql> SELECT COERCIBILITY('abc');
        -> 4

리턴되는 값은 아래 테이블에 설명된 의미를 갖는다. 값이 낮을 수로 높은 우선 순위를 갖는다.

 

Coercibility

Meaning

Example

0

Explicit collation

Value with COLLATE clause

1

No collation

Concatenation of strings with different collations

2

Implicit collation

Column value

3

System constant

USER() return value

4

Coercible

Literal string

5

Ignorable

NULL or an expression derived from NULL


MySQL 5.0.3 이전 버전의 경우, 리턴 값은 아래의 의미를 갖고 있었으며, USER() 와 같은 함수는 코에시빌러티가 2가 된다:

 

Coercibility

Meaning

Example

0

Explicit collation

Value with COLLATE clause

1

No collation

Concatenation of strings with different collations

2

Implicit collation

Column value, stored routine parameter or local variable

3

Coercible

Literal string

  • COLLATION(str)

스트링 인수의 콜레션을 리턴한다.

mysql> SELECT COLLATION('abc');
        -> 'latin1_swedish_ci'
mysql> SELECT COLLATION(_utf8'abc');
        -> 'utf8_general_ci'
  • CONNECTION_ID()

커넥션에 대한 커넥션 ID (쓰레드 ID)를 리턴한다. 모든 커넥션은 고유의 ID를 가지게 된다.

mysql> SELECT CONNECTION_ID();
        -> 23786
  • CURRENT_USER, CURRENT_USER()

서버가 현재의 클라이언트를 인증하기 위해 사용한 MySQL 계정에 대한 사용자 이름과 호스트 이름의 조합을 리턴한다. 이 계정은 여러분의 접속 권한을 결정한다. MySQL 5.0.10 버전까지는, SQL SECURITY DEFINER 특성으로 정의된 스토어드 루틴내에서, CURRENT_USER()은 루틴의 생성자 (creator)를 리턴한다. 리턴 값은 utf8 문자 셋에 있는 스트링이 된다.

CURRENT_USER()의 값은 USER()의 리턴 값과는 다르다.

mysql> SELECT USER();
        -> 'davida@localhost'
mysql> SELECT * FROM mysql.user;
ERROR 1044: Access denied for user ''@'localhost' to
database 'mysql'
mysql> SELECT CURRENT_USER();
        -> '@localhost'

위의 예제는, 클라이언트가 davida (USER() 함수가 가리키는 것 처럼)의 사용자 이름을 지정하였더라도, 서버는 익명의 사용자 이름 (CURRENT_USER() 값의 빈 사용자 이름 부분으로 보여지는)을 사용해서 클라이언트를 인증하고 있음을 보여 주는 것이다. 그 이유 중의 하나는 davida에 대한 그랜트 테이블에 아무런 계정 정보도 없기 때문이다.

  • DATABASE()

디폴트 (현재) 데이터 베이스 이름을 utf8 문자 셋의 스트링 형태로 리턴한다. 만일 데폴트 데이터베이스 이름이 존재하지 않는다면, DATABASE()NULL 을 리턴한다. 스토어드 루틴내에서는, 루틴이 연결되어 있는 데이터 베이스가 디폴트 데이터베이스가 되며, 이것이 반드시 호출 문맥 (context)에 있는 디폴트 데이터 베이스가 될 필요는 없다.

mysql> SELECT DATABASE();
        -> 'test'
  • FOUND_ROWS()

SELECT 명령문은 서버가 클라이언트에게 리턴하는 열의 숫자를 제한하기 위한 LIMIT 구문을 포함할 수도 있다. 어떤 경우에는, LIMIT 구문 없이 얼마나 많은 수의 열이 리턴되는지 알고 있는 것이 바람직하다. 이렇게 열의 숫자를 세기 위해서는, SELECT 명령문 안에 SQL_CALC_FOUND_ROWS 옵션을 추가하고, 나중에 FOUND_ROWS() 함수를 선언한다:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

두 번째 SELECTLIMIT 구문이 없이 작성된 첫 번째 SELECT가 얼마나 많은 열을 리턴했는지를 나타내는 숫자를 리턴한다. (만일 이전 SELECT 명령문에 SQL_CALC_FOUND_ROWS 옵션이 포함되어 있지 않다면, FOUND_ROWS()LIMIT가 사용되었을 경우와는 다른 결과를 리턴한다.)

 

FOUND_ROWS()를 통해서 셀 수 있는 열은 의미가 없으며, SELECT SQL_CALC_FOUND_ROWS 명령문 다음에 나오는 명령문들에도 의미가 없게 된다. 만일 나중에 이 값을 참조하고자 한다면, 우선 저장을 해 둔다:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
mysql> SET @rows = FOUND_ROWS();

만일 여러분이 SELECT SQL_CALC_FOUND_ROWS를 사용한다면, MySQL은 결과 셋 전체에 얼마나 많은 열이 있는지를 계산하게 된다. 하지만, 이렇게 하면 LIMIT 를 사용하지 않고 쿼리를 다시 구동시키는 것 보다 속도가 빨라지게 되는데, 그 이유는 결과 셋을 클라이언트에 전달할 필요가 없기 때문이다.

 

SQL_CALC_FOUND_ROWS FOUND_ROWS()는 쿼리가 리턴하는 열의 수를 제한하고자 할 때 뿐만 아니라, 쿼리를 다시 구동 시키지 않고서 전체 결과 셋에 있는 열의 숫자를 파악하고자 할 때 유용하게 사용할 수가 있는 함수이다. 어떤 검색 결과에 대한 다른 섹션을 보여주는 페이지에 대한 링크를 가지고 있는 페이지 디스플레이를 표현하는 웹 스크립트가 한 가지 예가 된다. FOUND_ROWS()를 사용하면 여러분은 결과 값의 나머지에 대해서 다른 페이지가 얼마나 필요한지를 알아낼 수가 있다.

 

SQL_CALC_FOUND_ROWS FOUND_ROWS()의 사용은 단순한 SELECT 명령문에 대해서 보다 UNION 명령문에 대해서가 훨씬 복잡한데, 그 이유는 LIMITUNION 내의 여러 곳에서 발생할 수가 있기 때문이다. UNION 내의 개별적인 SELECT 명령문에 적용하거나, 또는 전체적으로 UNION 결과에 적용할 수도 있다.

 

UNION 에 대해서 SQL_CALC_FOUND_ROWS를 사용하는 것은, 이것이 글로벌 LIMIT 없이 리턴되는 열 카운트를 리턴하기 때문이다. UNION 과 함께 SQL_CALC_FOUND_ROWS를 사용하는 조건은 다음과 같다:

    • SQL_CALC_FOUND_ROWS 키워드는 반드시 UNION의 맨 처음 SELECT 에 나타나야 한다.
    • FOUND_ROWS()의 값은 UNION ALL 이 사용되는 경우에만 정확하게 된다. 만일 UNION ALL  없이 사용된다면, 중복 제거가 발생하고 FOUND_ROWS()의 값은 추정치가 된다.
    • 만일 LIMIT UNION 내에 나타나면, SQL_CALC_FOUND_ROWS 은 무시가 되고 UNION을 처리하기 위해 생성된 임시 테이블에 있는 열의 숫자가 리턴된다.

 

  • LAST_INSERT_ID(), LAST_INSERT_ID(expr)

가장 최근의 INSERT 또는 UPDATE 명령문에 의해 AUTO_INCREMENT 컬럼용으로 설정된 값 중에 맨 처음으로 자동 생성된 값을 리턴한다.

mysql> SELECT LAST_INSERT_ID();
        -> 195

생성된 ID 는 커넥션 별로 서버에 의해 관리된다. , 이 함수에 의해 주어진 클라이언트에 리턴되는 값은 클라이언트에 의해 AUTO_INCREMENT 컬럼에 영향을 주는 가장 최근의 명령문을 위해 클라이언트가 생성한 맨 처음의 AUTO_INCREMENT 값이 된다. 이 값은 다른 클라이언트에 의해서는 영향을 받지 않게 되는데, 다른 클라이언트가 자신의 고유 AUTO_INCREMENT 값을 생성한다고 하더라도 마찬가지가 된다. 이러한 특성으로 인해 각각의 클라이언트는 다른 클라이언트의 행동에는 상관없이 자신만의 고유 ID를 가질 수 있게 되며, 락 또는 트랜젝션이 필요 없게 되는 것이다.

 

LAST_INSERT_ID()의 값은 여러분이 열의 AUTO_INCREMENT 컬럼을 비-“magic (, NULL 0 이 아닌 값)으로 설정한다면 변경되지 않는다.

 

Important: 만일 여러분이 하나의 INSERT 명령문을이용해서 여러 개의 열을 삽입한다면, LAST_INSERT_ID()은 맨 처음 삽입된 열에 대한 값만을 리턴하게 된다. 이렇게 되는 이유는, 다른 서버들에 대응해서 동일한 INSERT 명령문을 쉽게 재 생성할 수 있도록 하기 위함이다.

예문을 보도록 하자:

mysql> USE test;
Database changed
mysql> CREATE TABLE t (
    ->   id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
    ->   name VARCHAR(10) NOT NULL
    -> );
Query OK, 0 rows affected (0.09 sec)
 
mysql> INSERT INTO t VALUES (NULL, 'Bob');
Query OK, 1 row affected (0.01 sec)
 
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
|  1 | Bob  |
+----+------+
1 row in set (0.01 sec)
 
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+
1 row in set (0.00 sec)
 
mysql> INSERT INTO t VALUES
    -> (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
|  1 | Bob  |
|  2 | Mary |
|  3 | Jane |
|  4 | Lisa |
+----+------+
4 rows in set (0.01 sec)
 
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

비록 두 번째 INSERT 명령문이 3개의 새로운 열을 t 에 삽입하기는 하지만, 이렇게 삽입된 열중의 맨 처음 열을 위해 생성된 ID 2가 되며, 이 값이 뒤따라 나오는 SELECT 명령문을 위해 LAST_INSERT_ID()가 리턴하는 값이 되는 것이다.

 

만일 여러분이 NSERT IGNORE를 사용해서 그 열을 무시한다면, AUTO_INCREMENT 카운터는 증가하지 않게 되고 LAST_INSERT_ID()0 을 리턴하는데, 이것은 아무런 열도 삽입되지 않았다는 것을 의미하는 것이다.

 

만일 expr LAST_INSERT_ID()에 대한 인수 형태로 주어진다면, 그 인수의 값은 함수에 의해 리턴되고 LAST_INSERT_ID()에 의해 리턴되어야 할 다음 값으로 기억된다. 이것은 시퀀스를 시뮬레이트하기 위해 사용될 수가 있다:

 

  • 시퀀스 카운터를 가지고 있기 위한 테이블을 생성하고 초기화 시킨다:
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
  •  아래와 같이 시퀀스 숫자를 생성하기 위해 테이블을 사용한다:
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();

UPDATE 명령문은 시퀀스 카운터를 증가시키고 LAST_INSERT_ID()에 대한 다음 호출이 업데이트된 값을 리턴 하도록 만든다. SELECT 명령문은 그 값을 복구시킨다. mysql_insert_id() C API 함수 역시 이 값을 가져오는데 사용할 수가 있다. Section 22.2.3.36, “mysql_insert_id()를 참조할 것.

 

여러분은 LAST_INSERT_ID()를 호출하지 않고서도 시퀀스를 생성할 수 있지만, 위와 같은 방식으로 이 함수를 사용하는 것이 최종적으로 자동 생성된 값을 서버에서 유지 관리하는데 더 효율적이 된다. 여러 명의 클라이언트가 UPDATE 명령문을 실행해서 SELECT 명령문을 사용해서 자신들의 고유 시퀀스 값을 가져가기 때문에 이러한 방식이 더욱 안전한 것이다.

 

mysql_insert_id()INSERT UPDATE 명령문이 실행된이후에만 업데이트가 된다는 점을 알아두자. 따라서, 여러분은 SELECT 또는 SET과 같은 다른 SQL 명령문을 실행한 후에 LAST_INSERT_ID(expr)에 대한 값을 추출하기 위해 C API 함수를 사용할 수는 없게 된다.

  • ROW_COUNT()

ROW_COUNT()는 이전 명령문에 의해 업데이트, 삽입, 또는 삭제된 열의 숫자를 리턴한다. 이 값은 mysql_affected_rows() C API 함수로부터 얻는 열 카운트 값과 같은 값이 된다.

mysql> INSERT INTO t VALUES(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)
 
mysql> DELETE FROM t WHERE i IN(1,2);
Query OK, 2 rows affected (0.00 sec)
 
mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+
1 row in set (0.00 sec)

ROW_COUNT() MySQL 5.0.1에서 추가되었다.

  • SCHEMA()

이 함수는 DATABASE()과 동일한 것이며, MySQL 5.0.2에서 추가가 되었다.

  • SESSION_USER()

SESSION_USER()USER()과 동일한 함수다.

  • SYSTEM_USER()

SYSTEM_USER()USER()과 동일한 함수다.

  • USER()

현재의 MySQL 사용자 이름과 호스트 이름을 utf8 문자 셋의 스트링 형태로 리턴한다.

mysql> SELECT USER();
        -> 'davida@localhost'

결과 값은 여러분이 서버에 접속을 할 때 지정한 사용자 이름을 가리키게 되며, 여러분이 접속한 클라이언트 호스트가 된다. 이 값은 CURRENT_USER()의 값과 다른 값이다.

여러분은 아래와 같이 사용자 이름만 얻을 수도 있다:

mysql> SELECT SUBSTRING_INDEX(USER(),'@',1);
        -> 'davida'
  • VERSION()

MySQL  서버 버전을 가리키는 스트링을 리턴한다. 스트링은 utf8 문자 셋을 사용한다.

mysql> SELECT VERSION();
        -> '5.0.23-standard'

만일 여러분의 버전 스트링이 -log 로 끝난다면, 이것은 로깅이 현재 활성화 되어 있음을 의미하는 것이다.

posted by 우디냥
prev 1 next