5. mysql의 표준 호환성
5.1 mysql의 ANSI SQL92 확장부분
mysql에는 다른 sql 데이터베이스에서 찾을 수 없는 확장된 부분이 있다. 이런 부분을 사용
하는 경우 주의해야 한다. 왜냐면 mysql에서 사용한 코드가 다른 SQL 서버에 포팅할 수
없을 수도 있기 때문이다. 어떤 경우에는 /*! ... */ 형식의 주석문을 사용한 MYSQL 확장을
이용해 포팅가능한 코드를 만들 수 있다. 예를 들어보자:
SELECT /*! STRAIGHT_JOIN */ col_name from table1,table2 WHERE ...
MYSQL의 확장 부분은 다음과 같다:
- 필드타입 MEDIUMINT, SET, ENUM , 그리고 다른 BLOB 와 TEXT 타입.
- 필드속성 AUTO_INCREMENT, BINARY, UNSIGNED and ZEROFILL.
- 모든 문자열 비교는 기본적으로 대소문자를 구별하지 않으며 현재의 문자셋(기본적으로
ISO-8859-1 Latin1)에 의해 정렬 순서가 결정된다. 이것을 원하지 않으면 컬럼을 BINARY
속성으로 정의해야 하며 이런 경우에는 mysql 서버 호스트가 사용하는 ASCII 순서에 따라
문자열을 비교한다.
- MYSQL은 데이터베이스를 디렉토리로 만들고 테이블은 파일이름으로 만든다. 이것은 두
가지를 함축하고 있다:
ㅇ 파일이름의 대소문자를 구별하는 (대부분의 유닉스 시스템. 리눅스도 마찬가지겠지
용~) 운영 시스템에서는 MYSQL의 데이터베이스 이름과 테이블 이름은 대소문자를
구별한다. 테이블 이름을 기억하는데 문제가 있다면 모든 것을 소문자로 만들자.
ㅇ 테이블의 백업, 이름바꾸기, 옮기기, 삭제, 복사를 위해 표준 시스템 명령을 사용할
수 있다. 예를 들어 테이블의 이름을 바꾸려면 해당하는 테이블의 `.ISD', `.ISM' and
`.frm' 파일의 이름을 바꾸면 된다.
- SQL문에서 db_name.tbl_name 문을 이용하여 다른 데이터베이스의 테이블에 접근할 수
있다. 일부 SQL 서버는 같은 기능을 지원하지만 이것을 User space라고 부른다. MYSQL은
다음과 같은 TABLESPACES를 지원하지 않는다 : create table ralph.my_table...IN
my_tablespace.
- 수치(숫자형) 컬럼에서 LIKE를 사용할 수 있다.
- SELECT문에서 INTO OUTFILE 과 STRAIGHT_JOIN 을 사용할 수 있다. 7.11
[SELECT] 참고.
-EXPLIAN SELECT는 테이블에서 어떻게 조인이 되었는지에 대한 정보를 보여준다.
- Use of index names, indexes on a subpart of a field, and use of INDEX or KEY in a
CREATE TABLE statement. 7.6 [CREATE TABLE] 참고.
- ALTER TABLE에서 CHANGE col_name, DROP col_name 또는 DROP INDEX 를 사용
한다. 7.7 [ALTER TABLE] 참고.
- ALTER TABLE 문에서 IGNORE 사용.
- ALTER TABLE 문에서 다중 ADD, ALTER, DROP or CHANGE 사용
- IF EXISTS 키워드를 이용한 DROP TABLE 사용.
- 한 테이블 이상에서 DROP TABLE 사용.
- LOAD DATA INFILE 사용. 대부분의 경우 이 문장은 오라클의 LOAD DATA INFILE
과 호환된다. 7.15 [LOAD DATA INFILE] 참고.
(** 많은 양의 데이터를 한꺼번에 입력할 때 일일이 INSERT 문을 하는 것보다 속도가 빠
르다. **)
- OPTIMIZE TABLE 문 사용.
- 문자열은 ''' 만이 아니라 '"' 또는 ''' 로 닫을 수 있다.
- escape `\' 문자 사용.
- SET OPTION 문. 7.24 [SET OPTION] 참고.
- GROUP BY 부분에서 모든 컬럼을 사용할 필요가 없다. 이러한 기능은 일반적인 질의가
아닌 특정한 질의에서 성능을 향상시킨다. 7.3.12 [GROUP BY Functions] 참고.
(** ANSI SQL에서는 여러 테입믈을 이용하여 GROUP BY를 사용할 때 사용하고자 하는
모든 컬럼에 GROUP BY를 지정해 주어야 한다. 이렇게 되는 경우 불필요한 연산이 수행될
수 있는데 MYSQL에서는 이러한 것을 없앤 것이다. 7.3.12를 참고한다 **)
- 다른 SQL 환경을 사용했던 사용자를 위해 MYSQL은 많은 기능에서 알리아스를 지원한
다. 예를 들어 모든 문자 펑션은 ANSI SQL 과 ODBC 구문을 지원한다.
- MYSQL은 C 프로그래밍 언어와 같은 논리적인 OR 과 AND를 의미하는 || 와 && 를 인
식한다. MYSQL에서는 || 와 OR 는 같은 말이며 && 와 AND 도 마찬가지이다. 이러한 미
묘한 구문때문에 MYSQL은 string concatenation(문자열 연관, 연결?)을 위한 ANSI SQL
오퍼레이터인 || 을 지원하지 않는다. 대신 CONCAT()를 사용한다. CONCAT() 는 많은 인
자가 있어서 MYSQL 에서 || 오퍼레이터의 사용을 변환하기 쉽다.
MySQL understands the || and && operators to mean logical OR and AND, as in the C
programming language. In MySQL, || and OR are synonyms, as are && and AND.
Because of this nice syntax, MySQL doesn't support the ANSI SQL operator || for
string concatenation; use CONCAT() instead. Since CONCAT() takes any number of
arguments, it's easy to convert use of the || operator to MySQL.
- 포팅이 가능하도록 SQL CODE에서 STRAIGHT_JOIN같은 MYSQL만의 키워드 사용을
지원하기 위해 이런 키워드를 /* */ 주석안에 내장할 수 있다. 주석문안의 내용은 '!' 로 시
작한다. 이런 경우 MYSQL에서는 주석문을 다른 MYSQL 구문과 같이 해석하지만 다른
SQL 서버에서는 이러한 확장기능을 사용하지 않고 건너띌 수 있다. 예를 보자:
SELECT /*! STRAIGHT_JOIN */ * from table1,table2 WHERE ...
- 다음의 기능이나 명령 사용:
ㅇ CREATE DATABASE or DROP DATABASE. 7.4 [CREATE DATABASE] 참고.
ㅇ MOD() 대신에 % 사용. %는 C 프로그래머를 위해 지원하며 또한 PostgresSQL과의
호환성을 위해 지원한다.
ㅇ 컬럼 문에서 =, <>, <= ,<, >=,>, <<, >>, AND, OR, LIKE 사용.
ㅇ LAST_INSERT_ID(). 18.4.49 [mysql_insert_id()] 참고.
ㅇ REGEXP or NOT REGEXP.
ㅇ 하나나 하나 이상의 인자를 사용한 CONCAT() 나 CHAR(). MYSQL에서 이러한 펑
션은 여러개의 인자를 가질 수 있다.
ㅇ BIT_COUNT(), ELT(), FROM_DAYS(), FORMAT(), IF(), PASSWORD(),
ENCRYPT(), PERIOD_ADD(), PERIOD_DIFF(), TO_DAYS(), or WEEKDAY().
ㅇ 서브스트링을 없애는 데 TRIM() 사용.(Use of TRIM() to trim substrings) ANSI
SQL 에서는 단일 문자 제거만 지원한다.
(** 꺼어억~ 트림이 술먹고 하는 트림은 아니랍니다... **)
ㅇ 그룹 펑션에서 STD(), BIT_OR() and BIT_AND()
ㅇ DELET + INSERT 대신 REPLACE 사용. 7.14 [REPLACE] 참고.
ㅇ FLUSH flush_option 명령.
5.2 MYSQL에서 빠진 기능
다음의 기능들은 현재 버전의 MYSQL에 빠져있다. 다음 버전에서의 우선권을 확인하라면
MYSQL TODO 목록을 참고하자(http://www.mysql.com/Manual_split/manual_Todo.html).
이것이 가장 최신 버전의 TODO 목록이다. 부록 F [TODO] 참고.
5.2.1 Sub-selects
다음은 Mysql에서 작동하지 않는다:
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
Mysql에서는 오직 INSERT ... SELECT ... and REPLACE ... SELECT ... 만을 지원한다.
독립적인 서브-select 문은 3.23.0에서 아마도 사용할 수 있을 것이다. 그대신 현재 IN() 펑
션을 사용할 수 있다.
5.2.2 SELECT INTO TABLE
Mysql은 아직 SELECT ... INTO TABLE ....을 지원하지 않는다. 현재, Mysql은 오직
SELECT ... INTO OUTFILE ..., 만을 지원하며 기본적으로는 동일하다.
5.2.3 트랜잭션(Transactions)
트랜잭션은 지원되지 않는다. Mysql은 곧 atomic(원자성?) 오퍼레이션을 지원할 것이며
atomic 오퍼레이션은 rollback이 없는 트랜잭션과 비슷하다. atomic 오퍼레이션을 사용하며
insert/select/모든 명령의 그룹을 실행할 수 있으며 어떤 스레드도 충돌하지 않을 수 있도록
보장해준다. 이 문맥에서 일반적으로 롤백(rollback)은 필요없다. 현재 LOCK TABLES 와
UNLOCK TABLES 명령을 이용하여 다른 스레드가 충돌하는 것을 막을 수 있다. 7.23
[Lock Tables] 참고.
5.2.4 저장 프로시저와 트리거
저장 프로시저는 서버에서 컴파일되고 저장될 수 있는 SQL 명령 세트이다. 이런 기능이 수
행되면 클라이언트는 전체 질의를 다시 할 필요가 없고 또한 저장 프로시저를 참조할 수 있
다. 이런 기능이 있으면 질의는 한번만 해석되고 서버와 클라이언트간의 주고받아야 하는
데이터가 줄어들므로 속도가 향상된다. 또한 서버의 펑션 라이브러리를 가짐으로서 개념적
인 단계를 향상시킬 수 있다. (??? You can also raise the conceptual level by having
libraries of functions in the server.)
트리거는 특별한 이벤트가 발생했을 때 생기는 저장 프로시져이다. 예를 들어 트랜잭션 테
이블에서 레코드가 삭제되고 모든 트랜잭션이 지워질 때 상응하는 테이블을 삭제할 수 있는
저장 프로시저를 설치할 수 있다.
앞으로는 저장 프로시저를 지원할 예정이지만 트리거는 아니다. 트리거는 필요하지 않은 경
우에도 사용될 수 있어서 일반적으로 속도가 느려진다.
언제 저장 프로시저를 사용하게 될지는 앞으로 Mysql에 추가할 목록인 부록 F를 참고하
자.(The TODO)
(** 전반적으로 트랜잭션 처리와 트리거 등은 데이터베이스의 속도를 저하시킵니다. Mysql
은 이렇게 속도에 영향을 미칠 수 있는 부분을 제거하여 빠른 속도를 내는 것이지요. 이러
한 부분이 자기가 사용하는 데이터베이스에서 얼마나 중요한가 판단을 해 보아야 할 것입니
다. 보통 소형 DBMS에서는 회복과 병행수행을 지원하지 않는 경우가 많다. 즉 병행수행은
발생하지 않으며, 회복은 사용자의 문제로 생각한다. 그러므로 사용자가 데이터베이스의 예
비 사본을 준비하며, 고장이 발생하면 작업을 다시 해야 한다. 트리거같은 경우는 자료의 무
결성을 보장하기 위해 필요한 것이다. **)
5.2.5 외래키(Foreign Keys)
SQL 문에서 외래키는 테이블을 조인할 때 사용하지 않지만 대부분 참조 무결성을 확인할
때 사용한다. SELECT 문에서 다중 테이블에서 자료를 가져오길 원하면 테이블을 조인해서
처리할 수 있다.
SELECT * from table1,table2 where table1.id = table2.id
7.12 [JOIN] 참고.
Mysql에서 외래키(FOREIGN KEY) 문은 다른 SQL 제품의 CREATE TABLE 명령과의 호
환성 때문에 존재한다: 외래키는 아무것도 하지 않는다. ON DELETE ... 가 없는
FOREIGN KEY 구문은 대부분 문서적인 목적으로 사용한다. 일부 ODBC 애플리케이션은
이것을 자동적인 WHERE 문을 만들 때 사용할 것이다. 그렇지만 이것은 대부분 생략(무시)
하고 넘어가기 쉽다. 외래키는 때로는 제약조건 체크(constraint check)로 사용을 하지만 이
러한 체크는 데이터가 테이블에 정확한 순서로 들어갈때는 불필요하다. Mysql은 일부 애플
리케이션에서 외래키가 존재하는 것을 필요로 하기 때문에(제대로 작동하든 안하든 상관없
이) 지원하는 것일 뿐이다.
Mysql에서 외래키를 가진 테이블의 레코드를 삭제할 때 애플리케이션에 적절한 DELETE
문을 추가하여 ON DELETE ... 가 수행되는 것을 막음으로써 문제를 해결할 수있다. 경험
상 이렇게 하는 것이 외래키를 사용하는 것과 같이 빠르며(어떤 경우에는 더 빠름) 포팅하
기가 더 좋다.
가까운 시일안에 우리는 외래키 기능을 확장할 것이다. 그래서 최소한 mysqldump와 ODBC
에서 정보가 저장되고 검색할 수 있도록 할 것이다.
5.2.5.1 외래키를 사용하지 않는 이유
외래키를 사용할 때 어디에서 출발해야 할지 모르는 많은 문제가 있다:
- 외래키는 데이터베이스를 무척이나 복잡하게 만든다. 왜냐하면 외래키 정의는 데이터베이
스에 저장되어야 하고 외래키를 이행하는 것은 이동, 복사, 제거될 수 있는 파일을 사용하는
전체의 "사소한 접근"을 파괴할 것이다.
(** 번역이 이상한데 외래키가 있으면 참조 무결성 규칙을 위해 여러 가지 보상 연산을 하
게 된다. 이것을 뜻하고 있는 듯하다. **)
Foreign keys make life very complicated, because the foreign key definitions must be
stored in a database and implementing them would destroy the whole "nice approach" of
using files that can be moved, copied and removed.
- INSERT 와 UPDATE 문은 속도에 많은 영향을 끼친다. 그리고 이런 경우 보통 올바른
순서로 올바른 테이블에 레코드를 삽입하기 때문에 대부분 모든 외래키 체크는 사용할 필요
없다.
- 한쪽의 영향이 전체 데이터베이스에 연쇄 작용을 하기 때문에 테이블에서 업데이트를 할
때 매우 많은 테이블에서 락을 사용해야 한다. 한 테이블에서 먼저 레코드를 삭제하고 그후
에 다른 테이블에서 레코드를 삭제하는 것이 훨씬 빠르다.
- 테이블에서 완전하게 지울 때 테이블을 복구할 수 없고 ...
You can no longer restore a table by doing a full delete from the table and then
restoring all records (from a new source or from a backup).
- 외래키가 있다면 매우 특정한 순서로 하지 않는한 테이블을 덤프하고 복구할 수 없다.
If you have foreign keys you can't dump and restore tables unless you do so in a very
specific order.
- 단일 create 문에서 각 테이블을 재생성하는 것을 불가능하게 만드는 "allowd" circular
definition을 하는 것은 매우 쉽다. 정의가 작동을 하고 사용할 수 있다고 하더라도...
(** 으... 무슨 말??? **)
It's very easy to do "allowed" circular definitions that make the tables impossible to
recreate each table with a single create statement, even if the definition works and is
usable.
외래키의 좋은 점은 단지 다음와 같다. ODBC와 특정한 다른 클라이언트 프로그램에서 어
떻게 테이블이 연결되어 있는지를 볼 수 있고 연결 다이어그램을 보는데 사용하며 애플리케
이션을 만드는데 돕는 점이다.
The only nice aspect of foreign key is that it gives ODBC and some other client
programs the ability to see how a table is connected and use this to show connection
diagrams and to help building applicatons.
Mysql에서는 곧 외래키 정의를 저장할 수 있도록 해서 클라이언트가 어떻게 원래의 연결이
만들어졌는지에 대해서 질문하고 답을 받을 수 있도록 할 것이다. 현재의 '.frm' 파일 포맷
은 아직 이것을 지원하지 못하고 있다.
MySQL will soon store FOREIGN KEY definitions so that a client can ask for and
receive an answer how the original connection was made. The current `.frm' file format
does not have any place for it.
5.2.6 뷰
Mysql은 뷰를 지원하지 않는다. 그렇지만 TODO(이후 개선 목록)에 있다.
MySQL doesn't support views, but this is on the TODO.
5.2.7 `--'을 사용한 주석
일부 다른 SQL 데이터베이스는 '--' 로 주석을 시작한다. mysql 명령 라인 도구가 '--'로
시작하는 모든 줄을 제거할 지라도 Mysql은 '#'을 주석 문의 시작으로 사용한다. 사용자는
또한 C 명령 스타일인 /* this is a comment */ 를 mysql에서 사용할 수 있다. 7.28
[Comment] 참고.
Mysql은 '--'를 지원하지 않을 것이다; '--'은 퇴보한 주석문 형태로 자동으로 생성되는
SQL 질의에서 많은 문제를 발생시킨다. 다음의 예제를 보자. 우리는 자동적으로 payment를
!payment! 의 값으로 입력하도록 하고 있다 :
UPDATE tbl_name SET credit=credit-!payment!
payment의 값이 음수일 때 어떤 일이 생길 것이라 생각하는가?
1--1은 합당한 SQL문이기 때문에 '--'가 주석문의 시작을 의미하는 것을 꺼리는 것이다.
'--' 주석을 포함하는 텍스트 파일의 SQL 프로그램을 가졌다면 다음과 같이 사용해야 한다:
shell> replace " --" " #" < text-file-with-funny-comments.sql \
| mysql database
instead of the normal(정상적인 경우 대신???):
shell> mysql database < text-file-with-funny-comments.sql
명령 파일로 '--' 주석을 '#' 주석으로 바꿀 수 있다:
shell> replace " --" " #" -- text-file-with-funny-comments.sql
다음의 명령으로 원래대로 돌려놓자:
shell> replace " #" " --" -- text-file-with-funny-comments.sql
(** 일부 SQL에서 사용하는 -- 주석문에서 문제가 생길 수 있으므로 MYSQL에서는 #을
주석문으로 사용한다는 말이다 **)
5.3 Mysql이 따르고 있는 표준은 무엇인가?
Entry level SQL92. ODBC level 0-2.
5.4 BLOB 와 TEXT 타입의 제한
BLOB 나 TEXT 필드에서 GROUP BY 나 ORDER BY를 사용하길 원하면 그 필드를 고정
길이 객체로 만들어야 한다. 이렇게 하는 표준적인 방법은 SUBSTRING 펑션을 사용하는
것이다. 예를 보자:
mysql> select comment from tbl_name order by SUBSTRING(comment,20);
이렇게 하지 않으면 정렬할 때 오직 첫 번째 max_sort_lengths (기본값=1024)만을 고려된
다.
BLOB 와 TEXT 는 기본값을 가질 수 없으며 또한 언제나 NULL 컬럼일 것이다.
BLOB and TEXT cannot have DEFAULT values and will also always be NULL
columns.
5.5 COMMIT-ROLLBACK 없이 어떻게 대치할 수 있을까?
Mysql은 COMMIT-ROLLBACK 을 지원하지 않는다. 문제는 COMMIT-ROLLBACK을 효
과적으로 다루기 위해서는 Mysql에서 현재 사용하는 것과 완전히 다른 테이블 설계가 필요
하다는 것이다. Mysql은 또한 테이블을 자동 클린업하는 추가적인 스레드와 더 많은 디시
크를 사용할 수 있는 기능이 필요하다. 이러한 기능은 현재보다 mysql을 2-4배 느리게 만
든다. Mysql은 대부분의 다른 SQL 데이터베이스보다 훨씬 더 빠르다. (전형적으로 최소
2-3대 빠름) 이러한 이유는 Mysql에 COMMIT-ROLLBACK이 없기 때문이다.
당분간은 우리는 SQL 서버 언어의 성능을 향상시키는데 더 주력할 것이다. 대부분
COMMIT-ROLLBACK 기능이 정말로 필요한 경우는 드물다. 또한 이렇게 하는 것이 더 좋
은 성능을 낼 수 있다.
일반적으로 트랜잭션이 필요한 루트는 LOCK TABLES를 사용해 코드를 짤 수 있다. 또한
레코드를 업데이트할 때 커서를 사용할 필요가 없다.
우리는 트랜잭션과 커서를 TODO에 넣었지만 우선권이 높은 것은 아니다. 이러한 기능을
수행한다면 CREATE TABLE 의 옵션으로 될 것이다. 이것은 옵션으로 지정한 테이블에서
만 작동하며 그 테이블은 느리게 될 것이라는 것을 의미한다.
우리는 100% 보편적인 데이터보다는 정말로 빠른 데이터베이스가 필요하다.
COMMIT-ROLLBACK 기능을 수행하더라도 속도에 손상이 없다면 우리는 그것을 지원할
것이다. 당분간은 더 중요하게 해야할 일들이 많이 있다. 우리가 어떤 것에 우선권을 두고
있는지는 TODO를 참고하자. 상위 단계의 지원을 받는 고객은 이것을 바꿀 수 있으며 우선
권이 변경될 수도 있다.
현재의 문제는 실제로 ROLLBACK 이다. 롤백없이 LOCK TABLES을 이용하여 여러 종류
의 COMMIT를 사용할 수 있다. 롤백을 지원하기 위해 Mysql은 업데이트가 된 모든 예전
레코드를 저장하고 롤백이 일이났을 때 시작 시점으로 돌아갈 수 있도록 바꾸어야 한다. 예
를 들어 이러한 것은 전혀 어렵지 않다.(현재의 isamlog 는 이런 경우를 위해 사용할 수 있
다) 그러나 ALTER/DROP/CREATE TABLE에서 롤백을 수행하는 것은 무척 어렵다.
롤백 사용을 피하기 위해 다음의 전략을 사용할 수 있다:
1. 접근하기 원하는 모든 테이블에 락을 사용. LOCK TABLES ...
2. 조건 테스트(Test conditions)
3. 모든 것이 제대로 된다면 업데이트를 한다.
4. UNLOCK TABLES
일반적으로 가능한 롤백을 이용해 트랜잭션을 사용하는 것보다는 이러한 방법이 훨씬 더 빠
르다. 그렇지만 항상 사용가능한 것은 아니다. 이러한 방법으로 해결할 수 없는 유일한 상황
은 업데이트중 누군가가 스레드를 죽였을 때이다. 이런 경우 모든 락은 해제가 된다. 그렇지
만 업데이트의 일부는 실행되지 않을 것이다.
물론 단일 오퍼레이션에서 레코드를 업데이트하는 펑션을 사용할 수 있다. 다음의 테크닉을
사용하며 매우 효율적인 애플리케이션을 만들 수 있다:
- 현재 값과 관련되어 있는 필드를 수정
- 실제로 변화가 생겼을때만 필드를 업데이트
예를 들어, 어떤 고객 정보를 업데이트 할 때 오직 바뀐 데이터만 업데이트를 한다. 그리고
For example, when we are doing updates on some customer information, we update only
the customer data that have changed and test only that none of the changed data, or
data that depend on the changed data, have changed compared to the original row.
변화된 데이터의 테스트는 UPDATE 문에서 WHRE 절을 사용하여 할 수 있다. 레코드가
업데이트되지 않았다면 클라이언트에 다음과 같은 메시지를 준다: "당신이 바꾼 데이터 일
부가 다른 사용자에 의해 바뀌었습니다". 그러고나서 우리는 윈도우에서 예전의 레코드와
현재의 레코드를 비교하여 보여준다. 그러면 사용자는 어떤 고객 정보 레코드를 사용할지
결정할 수 있다.
이렇게 하면 "컬럼 라킹"과 비슷하다. 그렇지만 실제로는 더 빠르다. 왜냐하면 현재의 값과
관련되어 있는 값의 컬럼만 업데이트하기 때문이다. 이렇나 전형적인 업데이트문은 다음과
비슷할 것이다:
UPDATE tablename SET pay_back=pay_back+'relative change';
UPDATE customer
SET
customer_date='current_date',
address='new address',
phone='new phone',
money_he_owes_us=money_he_owes_us+'new_money'
WHERE
customer_id=id AND address='old address' AND phone='old phone';
지금 보듯이 이렇게 하면 매우 효율적이며 설사 다른 클라이언트가 pay_back 이나
money_he_owes_us 컬럼의 값을 바꾸었을 때라도 제대로 작동한다.
대부분의 경우, 사용자는 테이블에서 유일한 값(identifiers)을 관리하기 위해 롤백과 테이블
락을 사용하고 싶어한다. 이것은 AUTO_INCREMENT 컬럼과 SQL LAST_INSERT_ID()
펑션, 또는 mysql_insert_id() 의 C API 펑션을 사용하여 더욱 효율적으로 사용할 수 있다.
18.4.49 [mysql_insert_id()] 참고.
TcX에서는 언제나 이런 문제를 해결할 수 있기 때문에 결고 low-level 락을 필요로 하지
않는다. 어떤 경우에는 정말로 로우-락이 필요하다. 그렇지만 이런 경우는 극소수이다. 로우
-레벨 락을 원하면 테이블에서 플래그 컬럼을 사용할 수 있다. 다음과 같다:
UPDATE tbl_name SET row_flag=1 WHERE id=ID;
만약 row가 발견되고 row_flag가 원래의 row에서 이미 1이 아니라면 영향을 받은 row의
숫자로서 1일 반환한다.
MySQL returns 1 fro the number of affected rows if the row was found and row_flag
wasn't already 1 in the original row.