최근에 MySQL 이 "alter table"과 같은 DDL의 롤백을 지원 하지 않는다는 것을 알았습니다 ... PostgreSQL에 익숙해 져서 저를 놀라게했지만 제 친구는 오라클조차도 그것을 허용하지 않는다고 말했습니다. 지원하지 않는 기술적 이유가 있습니까? 단순히 "무관심한"기능입니까?
편집 : 방금 이 비교를 찾았습니다 . 트랜잭션 DDL을 지원 하는 많은 DBMS가 있는 것 같습니다 .
DROP
또는를 RENAME
?
최근에 MySQL 이 "alter table"과 같은 DDL의 롤백을 지원 하지 않는다는 것을 알았습니다 ... PostgreSQL에 익숙해 져서 저를 놀라게했지만 제 친구는 오라클조차도 그것을 허용하지 않는다고 말했습니다. 지원하지 않는 기술적 이유가 있습니까? 단순히 "무관심한"기능입니까?
편집 : 방금 이 비교를 찾았습니다 . 트랜잭션 DDL을 지원 하는 많은 DBMS가 있는 것 같습니다 .
DROP
또는를 RENAME
?
답변:
이것이 PostgreSQL에서 작동하는 이유는 시스템 카탈로그가 일반 테이블이기 때문입니다. 예를 들어, 새 함수를 만들려면 pg_proc
테이블에 행을 삽입하고 열의 기본값을 변경하면의 일부 행을 업데이트하기 만하면 pg_attrdef
됩니다. 어쨌든 테이블은 트랜잭션 방식이므로 거의 작동하지 않도록해야합니다. (많은 고통스러운 구현 세부 사항은 여기에서 생략되었습니다. ;-))
소스 코드를 모르면서 다른 데이터베이스 엔진이 일부 사용자 정의 내부 구조를 사용하여 시스템 카탈로그 정보를 나타내는 것으로 가정합니다. 따라서 트랜잭션 DDL을 작동 시키려면 많은 노력과 노력을 기울여야하며, 우선 순위는 아닙니다.
이것의 반대 측면은 이것이 PostgreSQL의 주요 버전 업그레이드가 너무 고통스러운 이유이기 때문입니다. 다른 제품은 변경 및 업데이트를 염두에두고 내부 메타 데이터 구조를 설계 할 수 있으므로 새 주요 버전으로 업그레이드하는 데 문제가 없습니다. PostgreSQL에서는 시스템 카탈로그에 액세스해야하기 때문에 시스템을 온라인 상태로 유지하는 동안 시스템 카탈로그 테이블을 갑자기 최신 버전의 시스템 카탈로그 테이블처럼 보이도록 변경할 수있는 방법이 없습니다. 어.
대부분 그렇지 않습니까? 버머.
나는 주로 SQL Server를 사용하지만 사용합니다. Oracle은 그렇지 않다는 것을 알고 있지만 Oracle은 수차 인 것으로 생각했습니다.
SQL Server에서는 단일 트랜잭션에서 여러 DDL 문을 실행할 수 있다고 확신하지만 두 가지 제한 사항 (모두 잊어 버렸습니다)이 있다고 생각합니다. 원하는 경우 대부분의 항목을 작성 또는 변경하거나 삭제하고 롤백 할 수 있습니다. Red-Gate SQL Compare (내가 좋아하는 도구)가 이것을 활용합니다.
이 작업의 문제점은 트랜잭션 범위가 상당히 흥미로워진다는 것입니다. DDL (업데이트 트랜잭션)에 시스템 카탈로그를 포함 시키면 실제로 중요한 잠금이 발생할 위험이 있으며 시스템 카탈로그에 대한 액세스가 차단 될 수 있습니다. 쿼리에서 카탈로그에서 테이블을 찾을 수 없으면 사용자가 많은 것을 할 수 없습니다!
그러나 균형을 유지하면서 다중 문 트랜잭션에 DDL을 포함시키는 것이 편리합니다.
보다 유용하게 SQL Server DDL 명령 TRUNCATE
은 다중 문 트랜잭션의 요소 일 수도 있습니다 . 대상 테이블을 자르고 (매우 빠름) 빌드 한 다음 결과가 마음에 들면 커밋을 수행 할 수 있습니다. 무언가 잘못되면 롤백하고 짜잔! 테이블을 방해하지 않은 것과 같습니다. 로그 공간도 최소화됩니다. 나는 그것을 자주 사용합니다.
SQL Server에서는 DDL 문을 롤백 할 수 있으며 명령문 끝에 자동 커밋을 사용하지 않습니다. 다른 DBMS에서는 알지 못하지만 Oracle에서는 동일한 작업을 수행 할 수 없다는 것을 기억합니다. 나는 그것이 각 DBMS에 고유하다고 생각하며, SQL 표준이 이것에 대해 무엇을 말할지 확실하지 않지만, 표준을 100 % 구현하는 생산자는 없다고 확신합니다.
SO에 대해서도 비슷한 질문이 있습니다. SQL Server 내에서 트랜잭션 내에서 여러 DDL 문을 실행할 수 있습니까?
Oracle은 쿼리 구문 분석을 공유 했으므로 한 세션에서 수행 한 SELECT * FROM table_a는 다른 세션과 동일합니다. 한 세션에 테이블에 열이 10 개 있다고 생각하고 다른 세션에 11 개가 있다고 생각하면 문제가 발생합니다.