문제

DB 스키마 변경을 추적 및/또는 자동화하는 가장 좋은 방법은 무엇입니까?우리 팀은 버전 제어를 위해 Subversion을 사용하고 이러한 방식으로 일부 작업을 자동화할 수 있었지만(스테이징 서버에 빌드 푸시, 테스트된 코드를 프로덕션 서버에 배포) 여전히 데이터베이스 업데이트를 수동으로 수행하고 있습니다.코드와 DB 업데이트가 다양한 서버에 푸시되는 백엔드로 Subversion을 계속 사용하면서 다양한 환경의 서버에서 효율적으로 작업할 수 있는 솔루션을 찾거나 만들고 싶습니다.

널리 사용되는 많은 소프트웨어 패키지에는 DB 버전을 감지하고 필요한 변경 사항을 적용하는 자동 업데이트 스크립트가 포함되어 있습니다.이것이 더 큰 규모(여러 프로젝트, 때로는 여러 환경 및 언어 전반)에서도 이를 수행하는 가장 좋은 방법입니까?그렇다면 프로세스를 단순화하는 기존 코드가 있습니까? 아니면 자체 솔루션을 출시하는 것이 가장 좋습니까?이전에 비슷한 것을 구현하여 Subversion 커밋 후 후크에 통합한 사람이 있습니까? 아니면 이것이 나쁜 생각입니까?

여러 플랫폼을 지원하는 솔루션이 더 바람직하지만 대부분의 작업이 Linux/Apache/MySQL/PHP 스택에서 이루어지기 때문에 Linux/Apache/MySQL/PHP 스택을 지원해야 합니다.

도움이 되었습니까?

해결책

Rails 세계에는 데이터베이스 관련 SQL이 아닌 Ruby로 데이터베이스 변경이 이루어지는 스크립트인 마이그레이션이라는 개념이 있습니다.Ruby 마이그레이션 코드는 결국 현재 데이터베이스에 특정한 DDL로 변환됩니다.이로 인해 데이터베이스 플랫폼 전환이 매우 쉬워졌습니다.

데이터베이스를 변경할 때마다 새 마이그레이션을 작성합니다.마이그레이션에는 일반적으로 두 가지 방법이 있습니다.변경 사항이 적용되는 "up" 방법과 변경 사항이 취소되는 "down" 방법입니다.단일 명령으로 데이터베이스를 최신 상태로 유지하고 데이터베이스를 특정 버전의 스키마로 가져오는 데에도 사용할 수 있습니다.Rails에서 마이그레이션은 프로젝트 디렉토리의 자체 디렉토리에 보관되며 다른 프로젝트 코드와 마찬가지로 버전 제어에 체크인됩니다.

Rails 마이그레이션에 대한 Oracle 가이드 마이그레이션을 꽤 잘 다룹니다.

다른 언어를 사용하는 개발자는 마이그레이션을 살펴보고 자체 언어별 버전을 구현했습니다.나는 알고있다 루킹, Rails의 마이그레이션을 모델로 한 PHP 마이그레이션 시스템입니다.그것은 당신이 찾고 있는 것일 수도 있습니다.

다른 팁

우리는 bcwood와 유사한 것을 사용하여 5개의 다른 설치(프로덕션, 준비 및 몇 가지 개발 설치)에서 데이터베이스 스키마를 동기화하고 버전 제어에서 백업했으며 꽤 잘 작동합니다.조금 더 자세히 설명하겠습니다.


데이터베이스 구조를 동기화하기 위해 단일 스크립트인 update.php와 1.sql, 2.sql, 3.sql 등으로 번호가 매겨진 여러 파일이 있습니다.스크립트는 하나의 추가 테이블을 사용하여 데이터베이스의 현재 버전 번호를 저장합니다.N.sql 파일은 데이터베이스 버전(N-1)에서 버전 N으로 이동하기 위해 손으로 제작됩니다.

테이블 추가, 열 추가, 이전 열 형식에서 새 열 형식으로 데이터 마이그레이션 후 열 삭제, 사용자 유형과 같은 "마스터" 데이터 행 삽입 등을 수행하는 데 사용할 수 있습니다.기본적으로 무엇이든 할 수 있으며 적절한 데이터 마이그레이션 스크립트를 사용하면 데이터가 손실되지 않습니다.

업데이트 스크립트는 다음과 같이 작동합니다.

  • 데이터베이스에 연결합니다.
  • 현재 데이터베이스를 백업해두세요. ~ 할 것이다 잘못됨) [mysqldump].
  • 존재하지 않는 경우 부기 테이블(_meta라고 함)을 만듭니다.
  • _meta 테이블에서 현재 버전을 읽습니다.찾을 수 없으면 0으로 가정합니다.
  • VERSION보다 높은 번호의 모든 .sql 파일에 대해 순서대로 실행하십시오.
  • 파일 중 하나에 오류가 발생한 경우:백업으로 롤백
  • 그렇지 않으면 장부 테이블의 버전을 실행된 가장 높은 .sql 파일로 업데이트하세요.

모든 것이 소스 제어로 들어가고 모든 설치에는 단일 스크립트 실행(적절한 데이터베이스 비밀번호로 update.php 호출 등)으로 최신 버전으로 업데이트하는 스크립트가 있습니다.SVN은 데이터베이스 업데이트 스크립트를 자동으로 호출하는 스크립트를 통해 스테이징 및 프로덕션 환경을 업데이트하므로 코드 업데이트는 필요한 데이터베이스 업데이트와 함께 제공됩니다.

또한 동일한 스크립트를 사용하여 전체 데이터베이스를 처음부터 다시 만들 수도 있습니다.데이터베이스를 삭제하고 다시 만든 다음 데이터베이스를 완전히 다시 채우는 스크립트를 실행하면 됩니다.또한 스크립트를 사용하여 자동화된 테스트를 위해 빈 데이터베이스를 채울 수도 있습니다.


이 시스템을 설정하는 데는 몇 시간밖에 걸리지 않았습니다. 개념적으로 간단하고 모든 사람이 버전 번호 체계를 알 수 있으며, 수정 내용을 전달하거나 수동으로 실행하지 않고도 데이터베이스 설계를 발전시키고 발전시킬 수 있는 능력을 갖추는 데 매우 중요했습니다. 모든 데이터베이스에서.

하지만 phpMyAdmin에서 쿼리를 붙여넣을 때는 주의하세요! 생성된 쿼리에는 일반적으로 데이터베이스 이름이 포함되는데, 이는 스크립트를 손상시킬 수 있으므로 절대 원하지 않습니다!CREATE TABLE과 같은 것 mydb.newtable(...)는 시스템의 데이터베이스가 mydb라고 불리지 않으면 실패합니다.우리는 다음을 포함하는 .sql 파일을 허용하지 않는 사전 주석 SVN 후크를 만들었습니다. mydb 이는 누군가 적절한 확인 없이 phpMyAdmin에서 복사하여 붙여넣었다는 확실한 신호입니다.

우리 팀은 모든 데이터베이스 변경 사항을 스크립트로 작성하고 애플리케이션의 각 릴리스와 함께 해당 스크립트를 SVN에 커밋합니다.이를 통해 데이터 손실 없이 데이터베이스를 점진적으로 변경할 수 있습니다.

한 릴리스에서 다음 릴리스로 이동하려면 변경 스크립트 세트를 실행하기만 하면 됩니다. 그러면 데이터베이스가 최신 상태로 유지되고 모든 데이터가 그대로 유지됩니다.가장 쉬운 방법은 아닐 수도 있지만 확실히 효과적입니다.

여기서 문제는 개발자가 자신의 로컬 변경 사항을 소스 제어에 스크립팅하여 팀과 공유하는 것을 쉽게 만드는 것입니다.저는 수년 동안 이 문제에 직면해 왔으며 데이터베이스 전문가를 위한 Visual Studio의 기능에 영감을 받았습니다.동일한 기능을 갖춘 오픈 소스 도구를 원한다면 다음을 시도해 보십시오. http://dbsourcetools.codeplex.com/ 재미있어, -Nathan.

아직도 해결책을 찾고 있다면:우리는 neXtep 디자이너라는 도구를 제안하고 있습니다.전체 데이터베이스를 버전 제어할 수 있는 데이터베이스 개발 환경입니다.모든 변경 사항을 추적할 수 있는 버전 관리 저장소에서 작업합니다.

업데이트를 릴리스해야 하는 경우 구성 요소를 커밋하면 제품이 이전 버전에서 SQL 업그레이드 스크립트를 자동으로 생성합니다.물론 두 가지 버전 모두에서 이 SQL을 생성할 수 있습니다.

그러면 다음과 같은 다양한 옵션이 있습니다.해당 스크립트를 가져와서 앱 코드와 함께 SVN에 넣으면 기존 메커니즘에 의해 배포될 수 있습니다.또 다른 옵션은 neXtep의 전달 메커니즘을 사용하는 것입니다.스크립트는 "배달 패키지"(SQL 스크립트 + XML 설명자)라는 이름으로 내보내지며, 설치 프로그램은 이 패키지를 이해하고 구조적 일관성, 종속성 확인, 설치된 버전 등록 등을 확인하면서 대상 서버에 배포할 수 있습니다.

이 제품은 GPL이며 Eclipse를 기반으로 하므로 Linux, Mac 및 Windows에서 실행됩니다.또한 현재 Oracle, Mysql 및 Postgresql을 지원합니다(DB2 지원이 진행 중입니다).더 자세한 정보를 찾을 수 있는 위키를 살펴보세요.http://www.nextep-softwares.com/wiki

스키마를 파일로 덤프하고 소스 제어에 추가합니다.그런 다음 간단한 차이점을 통해 무엇이 변경되었는지 확인할 수 있습니다.

Scott Ambler는 훌륭한 일련의 기사를 작성하고 ) 데이터베이스 리팩토링에 대해, 스키마 유지 관리에 TDD 원칙과 관행을 본질적으로 적용해야 한다는 생각을 가지고 있습니다.데이터베이스에 대한 일련의 구조 및 시드 데이터 단위 테스트를 설정합니다.그런 다음 무엇이든 변경하기 전에 해당 변경 사항을 반영하도록 테스트를 수정/작성합니다.

우리는 한동안 이 일을 해왔고 효과가 있는 것 같습니다.단위 테스트 모음에서 기본 열 이름과 데이터 유형 검사를 생성하는 코드를 작성했습니다.SVN 체크아웃의 데이터베이스가 애플리케이션이 실제로 실행 중인 라이브 DB와 일치하는지 확인하기 위해 언제든지 해당 테스트를 다시 실행할 수 있습니다.

결과적으로 개발자는 때때로 샌드박스 데이터베이스를 조정하고 SVN의 스키마 파일 업데이트를 무시하는 경우도 있습니다.그런 다음 코드는 체크인되지 않은 DB 변경 사항에 따라 달라집니다.그런 종류의 버그는 찾아내기가 엄청나게 어려울 수 있지만 테스트 스위트에서는 즉시 이를 찾아낼 것입니다.이는 더 큰 지속적 통합 계획에 내장되어 있는 경우 특히 좋습니다.

케이.Scott Allen은 여기의 다른 답변에서 참조된 증분 업데이트 스크립트/마이그레이션 개념을 사용하는 스키마 버전 관리에 대한 괜찮은 기사를 한두 개 가지고 있습니다.보다 http://odetocode.com/Blogs/scott/archive/2008/01/31/11710.aspx.

이는 다소 낮은 기술이고 더 나은 솔루션이 있을 수 있지만 데이터베이스를 생성하기 위해 실행할 수 있는 SQL 스크립트에 스키마를 저장할 수 있습니다.이 스크립트를 생성하기 위해 명령을 실행할 수 있다고 생각하지만 불행히도 그 명령을 모릅니다.

그런 다음 스크립트를 작동하는 코드와 함께 소스 제어에 커밋합니다.코드와 함께 스키마를 변경해야 하는 경우 변경된 스키마가 필요한 코드와 함께 스크립트를 체크인할 수 있습니다.그런 다음 스크립트의 차이점은 스키마 변경 사항에 대한 차이점을 나타냅니다.

이 스크립트를 사용하면 DBUnit이나 일종의 빌드 스크립트와 통합할 수 있으므로 이미 자동화된 프로세스에 적합할 것 같습니다.

C#을 사용하는 경우 매우 유용한 ORM 도구인 Subsonic을 살펴보세요. 또한 구성표 및/또는 데이터를 다시 생성하기 위한 SQL 스크립트도 생성합니다.그런 다음 이러한 스크립트를 소스 제어에 넣을 수 있습니다.

http://subsonicproject.com/

여러 프로젝트에 대해 Visual Studio에서 다음 데이터베이스 프로젝트 구조를 사용했는데 꽤 잘 작동했습니다.

데이터 베이스

스크립트 변경

0.PreDeploy.sql

1.SchemaChanges.sql

2.DataChanges.sql

3.권한.sql

스크립트 만들기

스프록

기능

견해

그런 다음 빌드 시스템은 다음 순서로 스크립트를 실행하여 데이터베이스를 한 버전에서 다음 버전으로 업데이트합니다.

1.PreDeploy.sql

2.SchemaChanges.sql

Create Scripts 폴더의 내용

2.DataChanges.sql

3.권한.sql

각 개발자는 각 파일 끝에 자신의 코드를 추가하여 특정 버그/기능에 대한 변경 사항을 확인합니다.주요 버전이 완료되고 소스 제어에서 분기되면 변경 스크립트 폴더에 있는 .sql 파일의 내용이 삭제됩니다.

우리는 매우 간단하면서도 효과적인 솔루션을 사용합니다.

새로 설치하는 경우 저장소에 모든 DB 스키마를 보유하는 메타데이터.sql 파일이 있으며, 빌드 프로세스에서 이 파일을 사용하여 데이터베이스를 생성합니다.

업데이트의 경우 하드코딩된 소프트웨어에 업데이트를 추가합니다.우리는 문제가 실제로 발생하기 전에 문제를 해결하는 것을 좋아하지 않기 때문에 이를 하드코딩해 두고 있으며, 이런 종류의 일은 지금까지 문제가 되지 않은 것으로 입증되었습니다.

따라서 우리 소프트웨어에는 다음과 같은 것이 있습니다.

RegisterUpgrade(1, 'ALTER TABLE XX ADD XY CHAR(1) NOT NULL;');

이 코드는 데이터베이스가 버전 1(자동으로 생성된 테이블에 저장됨)인지 확인하고, 오래된 경우 명령을 실행합니다.

저장소의 메타데이터.sql을 업데이트하기 위해 이 업그레이드를 로컬로 실행한 다음 전체 데이터베이스 메타데이터를 추출합니다.

자주 발생하는 유일한 일은 메타데이터.sql 커밋을 잊어버리는 것입니다. 그러나 이는 빌드 프로세스에서 테스트하기 쉽고 발생할 수 있는 유일한 일은 다음을 사용하여 새로 설치하는 것이므로 큰 문제는 아닙니다. 오래된 데이터베이스를 처음 사용할 때 업그레이드했습니다.

또한 우리는 다운그레이드를 지원하지 않지만 의도적으로 설계된 것입니다. 업데이트에서 문제가 발생하면 이전 버전을 복원하고 다시 시도하기 전에 업데이트를 수정합니다.

빌드 버전 이름을 딴 폴더를 만들고 거기에 업그레이드 및 다운그레이드 스크립트를 넣습니다.예를 들어 다음과 같은 폴더가 있을 수 있습니다.1.0.0, 1.0.1, 1.0.2.각 버전에는 버전 간에 데이터베이스를 업그레이드하거나 다운그레이드할 수 있는 스크립트가 포함되어 있습니다.

클라이언트나 고객이 버전 1.0.1에 문제가 있다고 전화하고 귀하가 1.0.2를 사용하고 있는 경우 데이터베이스를 해당 버전으로 되돌리는 것은 문제가 되지 않습니다.

데이터베이스에서 현재 버전의 데이터베이스를 넣을 "스키마"라는 테이블을 만듭니다.그렇다면 데이터베이스를 업그레이드하거나 다운그레이드할 수 있는 프로그램을 작성하는 것은 쉽습니다.

Joey가 말했듯이 Rails 세계에 있다면 마이그레이션을 사용하세요.:)

현재 PHP 프로젝트에서는 레일 마이그레이션 아이디어를 사용하고 있으며 파일 제목이 "migration_XX.sql"인 마이그레이션 디렉토리가 있습니다. 여기서 XX는 마이그레이션 번호입니다.현재 이러한 파일은 업데이트가 이루어지면 수동으로 생성되지만 생성된 내용은 쉽게 수정할 수 있습니다.

그런 다음 "Migration_watcher"라는 스크립트가 있습니다. 이 스크립트는 알파 이전 버전이므로 현재 모든 페이지 로드 시 실행되며 XX가 현재 마이그레이션 버전보다 큰 새 migration_XX.sql 파일이 있는지 확인합니다.그렇다면 데이터베이스에 대해 최대 수까지 모든 migration_XX.sql 파일을 실행합니다. 짜잔!스키마 변경이 자동화됩니다.

시스템을 되돌리는 기능이 필요한 경우 많은 조정이 필요하지만 이는 간단하며 지금까지 꽤 작은 팀에서는 매우 잘 작동해 왔습니다.

"스크립팅" 측면에는 Ant(크로스 플랫폼)를 사용하고(jdbc를 통해 실제로 모든 DB와 통신할 수 있기 때문에) 소스 저장소에는 Subversion을 사용하는 것이 좋습니다.Ant를 사용하면 변경하기 전에 DB를 로컬 파일로 "백업"할 수 있습니다.1.기존 DB 스키마 백업 ANT 2를 통해 파일.개미 3을 통한 전복 저장소에 대한 버전 제어.Ant를 통해 새 SQL 문을 db로 보냅니다.

Toad for MySQL에는 2개의 데이터베이스를 동기화할 수 있는 스키마 비교라는 기능이 있습니다.지금까지 사용해 본 도구 중 최고의 도구입니다.

IMHO 마이그레이션에는 큰 문제가 있습니다.

한 버전에서 다른 버전으로 업그레이드하는 것은 잘 작동하지만, 수백 개의 테이블이 있고 변경 내역이 긴 경우(저희처럼) 특정 버전을 새로 설치하는 데 시간이 오래 걸릴 수 있습니다.

기준선부터 현재 버전(수백 개의 고객 데이터베이스)까지 델타의 전체 기록을 실행하는 데는 매우 오랜 시간이 걸릴 수 있습니다.

나는 그 방식을 좋아한다. 데이터베이스 마이그레이션을 처리합니다.마이그레이션은 기본적으로 PHP 스크립트를 구현하는 것입니다. CDbMigration. CDbMigration 정의 up 마이그레이션 논리가 포함된 메서드입니다.을 구현하는 것도 가능합니다. down 마이그레이션 취소를 지원하는 방법입니다.대안적으로, safeUp 또는 safeDown 트랜잭션 컨텍스트에서 마이그레이션이 수행되었는지 확인하는 데 사용할 수 있습니다.

Yii의 명령줄 도구 yiic 마이그레이션을 생성하고 실행하는 지원이 포함되어 있습니다.마이그레이션은 하나씩 또는 일괄적으로 적용하거나 되돌릴 수 있습니다.마이그레이션을 생성하면 PHP 클래스 구현을 위한 코드가 생성됩니다. CDbMigration, 타임스탬프와 사용자가 지정한 마이그레이션 이름을 기반으로 고유하게 이름이 지정됩니다.이전에 데이터베이스에 적용된 모든 마이그레이션은 마이그레이션 테이블에 저장됩니다.

자세한 내용은 다음을 참조하세요. 데이터베이스 마이그레이션 매뉴얼의 기사.

db-deploy를 사용해 보세요. 주로 Java 도구이지만 PHP에서도 작동합니다.

명령줄이 있습니다. mysql-diff 데이터베이스 스키마를 비교하는 도구입니다. 여기서 스키마는 라이브 데이터베이스이거나 디스크의 SQL 스크립트일 수 있습니다.대부분의 스키마 마이그레이션 작업에 적합합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top