DB 스키마 변경 사항을 추적하는 메커니즘 [닫기]


135

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

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

여러 플랫폼을 지원하는 솔루션이 바람직하지만, 대부분의 작업이 해당 플랫폼에 있으므로 Linux / Apache / MySQL / PHP 스택을 지원해야합니다.

답변:


56

Rails 세계에는 데이터베이스 고유의 SQL 형식이 아닌 Ruby로 데이터베이스를 변경하는 마이그레이션 개념 인 마이그레이션이라는 개념이 있습니다. Ruby 마이그레이션 코드는 현재 데이터베이스에 특정한 DDL로 변환됩니다. 따라서 데이터베이스 플랫폼 전환이 매우 쉽습니다.

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

이 Rails 마이그레이션 가이드 는 마이그레이션에 대해 잘 설명합니다.

다른 언어를 사용하는 개발자는 마이그레이션을 살펴보고 고유 한 언어 별 버전을 구현했습니다. Rails의 마이그레이션을 모델로 한 PHP 마이그레이션 시스템 인 Ruckusing 에 대해 알고 있습니다 . 당신이 찾고있는 것일 수도 있습니다.


1
Ruckusing FTW-우리는이를 DB 시스템에 적용했으며 매우 만족합니다.
Piskvor

현재 github에 있습니다 : github.com/ruckus/ruckusing-migrations

50

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


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

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

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

  • 데이터베이스에 연결하십시오.
  • 현재 데이터베이스 (물건 때문에 백업 확인 합니다 잘못) mysqldump를]를.
  • 부기 테이블 (_meta)이 없으면 만듭니다.
  • _meta 테이블에서 현재 VERSION을 읽습니다. 찾을 수 없으면 0으로 가정하십시오.
  • 버전이 VERSION보다 높은 모든 .sql 파일에 대해 순서대로 실행하십시오.
  • 파일 중 하나에서 오류가 발생한 경우 백업으로 롤백
  • 그렇지 않으면 부기 테이블의 버전을 실행 된 가장 높은 .sql 파일로 업데이트하십시오.

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

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


이 시스템을 설정하는 데 몇 시간 밖에 걸리지 않았으며 개념적으로 간단하고 모든 사람이 버전 번호 매기기 체계를 얻었으며 수정 사항을 수동으로 실행하거나 전달하지 않고도 데이터베이스 디자인을 발전시키고 발전시킬 수 있다는 점에서 매우 귀중했습니다. 모든 데이터베이스에서.

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


충돌을 어떻게 처리 했습니까? 여러 개발자가 DB에서 동일한 요소를 변경하는 경우 (예 : 저장 프로 시저) 같은 지점에서 같은 곳에서 일하거나 두 개의 개발 라인이있는 경우 (두 지점)
Asaf Mesika

충돌은 매우 드;니다. 실제로 일어난 유일한 일은 두 사람이 동일한 N.sql 파일을 만들려고한다는 것입니다. 물론, 첫 번째는 이기고 두 번째는 다음으로 높은 숫자로 이름을 바꾸고 다시 시도해야합니다. 하지만 지점에는 데이터베이스 버전이 없습니다.
rix0rrr

12

우리 팀은 모든 데이터베이스 변경 사항을 스크립트로 작성하고 각 응용 프로그램 릴리스와 함께 해당 스크립트를 SVN에 커밋합니다. 이를 통해 데이터 손실없이 데이터베이스를 증분 적으로 변경할 수 있습니다.

한 릴리스에서 다음 릴리스로 이동하려면 일련의 변경 스크립트를 실행하기 만하면되고 데이터베이스는 최신 상태이며 여전히 모든 데이터를 가지고 있습니다. 가장 쉬운 방법은 아니지만 확실히 효과적입니다.


1
모든 변경 사항을 어떻게 스크립트합니까?
Smith

10

여기서 문제는 실제로 개발자가 자신의 로컬 변경 사항을 소스 제어에 스크립팅하여 팀과 쉽게 공유 할 수 있도록하는 것입니다. 나는 수년간이 문제에 직면 해 왔으며 Visual Studio for Database 전문가의 기능에서 영감을 얻었습니다. 동일한 기능을 가진 오픈 소스 도구를 원한다면 다음을 시도하십시오. http://dbsourcetools.codeplex.com/ 즐거운 시간 보내십시오-Nathan.


10

여전히 솔루션을 찾고 있다면 : neXtep designer이라는 도구를 제안합니다. 전체 데이터베이스를 버전 제어하에 둘 수있는 데이터베이스 개발 환경입니다. 모든 변경 사항을 추적 할 수있는 버전 제어 저장소에서 작업합니다.

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

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

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


재미있어 보인다. 명령 줄 인터페이스도 있습니까? 아니면 계획되어 있습니까?
Piskvor가

8

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

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

결과적으로 개발자는 때때로 샌드 박스 데이터베이스를 조정하고 SVN에서 스키마 파일을 업데이트하지 않습니다. 그런 다음 코드는 체크인되지 않은 DB 변경에 따라 달라집니다. 이러한 종류의 버그는 매우 까다로울 수 있지만 테스트 스위트는 즉시이를 선택합니다. 더 큰 Continuous Integration 계획에 내장되어 있으면 특히 좋습니다.


7

스키마를 파일로 덤프하고 소스 제어에 추가하십시오. 그런 다음 간단한 diff가 변경된 것을 보여줍니다.


1
덤프는 mysqldump와 같이 SQL에 있어야하며 Oracle의 덤프는 이진입니다.
Osama Al-Maadeed

7
스키마 디핑에는 더 근본적인 문제가 있습니다. 열 삭제 + 추가와 열 이름 변경을 어떻게 구별합니까? 대답은 간단합니다. 할 수 없습니다. 이것이 실제 스키마 변경 작업을 기록해야하는 이유입니다.
psp

diff는 하나의 열이 사라졌고 다른 열은 같은 이름이 아닌 한 나타 났으며 대부분은 충분하다는 것을 보여줍니다. 물론 모든 스키마 변경을 스크립팅하는 것이 좋은 방법입니다. Drupal에서는 예를 들어 특수 후크로 처리합니다.
deadprogrammer


5

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

그런 다음 스크립트를 작동하는 코드와 함께 소스 제어로 스크립트를 커미트하십시오. 코드와 함께 스키마를 변경해야하는 경우 변경된 스키마가 필요한 코드와 함께 스크립트를 체크인 할 수 있습니다. 그런 다음 스크립트의 diff는 스키마 변경에 대한 diff를 나타냅니다.

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


네, 지금 우리가 가진 것입니다. 불행히도 기존 데이터베이스를 쉽게 수정할 수있는 방법을 제공하지는 않습니다 .mysqldump에 의해 생성 된 SQL 스크립트는 테이블을 처음부터 작성한다고 가정합니다 (또는 존재하는 경우 테이블을 덮어 씁니다). ALTER TABLE 문 시퀀스를 데이터베이스에 적용해야하기 때문에 좀 더 첨단 기술이 필요합니다.이를 위해서는 데이터베이스의 현재 상태를 알아야합니다.
pix0r

5

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

http://subsonicproject.com/


이 시점에서 사용 불능 URL 인 것 같습니다.
Mark Schultheiss

5

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

데이터 베이스

스크립트 변경

0.PreDeploy.sql

1. 스키마 변경 .sql

2.DataChanges.sql

3.Permissions.sql

스크립트 작성

절차

기능

견해

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

1. PreDeploy.sql

2. 스키마 변경 .sql

스크립트 작성 폴더의 내용

2.DataChanges.sql

3.Permissions.sql

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


5

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

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

업데이트를 위해 하드 코드 된 소프트웨어에 업데이트를 추가합니다. 우리는 실제로 문제가되기 전에 문제를 해결하는 것을 좋아하지 않기 때문에 하드 코딩 된 상태로 유지합니다. 이런 종류의 문제는 지금까지 문제가되지 않았습니다.

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

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

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

리포지토리에서 metadata.sql을 업데이트하기 위해이 업그레이드를 로컬로 실행 한 다음 전체 데이터베이스 메타 데이터를 추출합니다.

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

또한 다운 그레이드를 지원하지 않지만 의도적으로 업데이트에 문제가있는 경우 이전 버전을 복원하고 다시 시도하기 전에 업데이트를 수정합니다.


4

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

클라이언트 또는 고객이 1.0.1 버전의 문제로 전화를 걸고 1.0.2를 사용하는 경우 데이터베이스를 그의 버전으로 다시 가져 오는 것은 문제가되지 않습니다.

데이터베이스에서 현재 버전의 데이터베이스에 "schema"라는 테이블을 작성하십시오. 그런 다음 데이터베이스를 업그레이드하거나 다운 그레이드 할 수있는 프로그램을 작성하는 것이 쉽습니다.

Joey가 말한 것처럼 Rails 환경에있는 경우 마이그레이션을 사용하십시오. :)


3

현재 PHP 프로젝트에서는 rails migration이라는 아이디어를 사용하고 파일 이름을 "migration_XX.sql"로 유지하는 migrations 디렉토리가 있습니다. 여기서 XX는 마이그레이션 횟수입니다. 현재 이러한 파일은 업데이트 할 때 수동으로 만들어 지지만 쉽게 만들 수 있습니다.

그리고 사전 알파에서와 같이 현재 모든 페이지로드에서 실행되고 XX가 현재 마이그레이션 버전보다 큰 새 migration_XX.sql 파일이 있는지 확인하는 "Migration_watcher"라는 스크립트가 있습니다. 그렇다면 모든 migration_XX.sql 파일을 데이터베이스와 voila에 대해 가장 큰 수까지 실행합니다! 스키마 변경이 자동화됩니다.

시스템을 되돌릴 수있는 기능이 필요한 경우에는 많은 조정이 필요하지만 간단하고 지금까지 우리의 소규모 팀을 위해 매우 잘 작동했습니다.


3

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


3

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


3

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

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

자세한 정보 는 매뉴얼 의 데이터베이스 마이그레이션 기사를 참조하십시오 .



2

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

한 버전에서 다른 버전으로 업그레이드해도 문제가 없지만 수백 개의 테이블과 긴 변경 기록 (예 : 우리처럼)이있는 경우 지정된 버전을 새로 설치하는 데 시간이 오래 걸릴 수 있습니다.

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


0

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.