[database] 소스 제어에서 데이터베이스를 어떻게 구축해야합니까?

SO 커뮤니티 위키에서 데이터베이스 개체의 버전을 제어해야하는지 여부에 대한 논의가있었습니다. 그러나 데이터베이스 개체에 대한 빌드 자동화 프로세스를 만드는 모범 사례에 대한 논의를 많이 보지 못했습니다.

특히 개발자와 DBA는 데이터베이스 배포에 대한 자동화 접근 방식의 이점과 위험을 평가할 때 종종 다른 목표, 접근 방식 및 우려 사항을 가지고 있기 때문에 이것은 우리 팀에게 논쟁의 여지가있는 부분이었습니다.

실제 세계에서 어떤 관행이 효과적 이었는지에 대한 SO 커뮤니티의 아이디어를 듣고 싶습니다.

어떤 관행이 정말로 최선인지가 다소 주관적이라는 것을 알고 있지만 어떤 작업이 많은 사람들에게 도움이 될 수 있는지에 대한 좋은 대화가 있다고 생각합니다.

다음은이 주제의 관심 영역에 대한 몇 가지 티저 질문입니다. 이것들은 결정적인 목록이 아니라 사람들이 내가 찾고있는 것을 이해하는 데 도움이되는 출발점입니다.

  1. 테스트 및 프로덕션 환경 모두 소스 제어에서 구축해야합니까?
    • 둘 다 자동화를 사용하여 구축해야합니까? 아니면 안정적이고 최종화 된 테스트 환경에서 개체를 복사하여 구축해야합니까?
    • 배포 스크립트에서 테스트 환경과 프로덕션 환경 간의 잠재적 인 차이점을 어떻게 처리합니까?
    • 배포 스크립트가 테스트 에서처럼 프로덕션에 대해 효과적으로 작동하는지 어떻게 테스트합니까?
  2. 어떤 유형의 객체를 버전 관리해야합니까?
    • 코드 (프로 시저, 패키지, 트리거, Java 등) 만 있습니까?
    • 인덱스?
    • 제약?
    • 테이블 정의?
    • 테이블 변경 스크립트? (예 : ALTER 스크립트)
    • 모두?
  3. 어떤 유형의 객체가 버전 제어되지 않아야합니까?
    • 시퀀스?
    • 보조금?
    • 사용자 계정?
  4. SCM 저장소에서 데이터베이스 개체를 어떻게 구성해야합니까?
    • 변환 스크립트 또는 ALTER 스크립트와 같은 일회성 작업을 어떻게 처리합니까?
    • 데이터베이스에서 폐기되는 객체를 어떻게 처리합니까?
    • 개체를 개발에서 테스트 수준으로 승격하는 책임자는 누구 입니까?
    • 여러 개발자의 변경 사항을 어떻게 조정합니까?
    • 여러 시스템에서 사용하는 데이터베이스 개체의 분기를 어떻게 처리합니까?
  5. 이 프로세스에 대해 어떤 예외가 합리적 일 수 있습니까?
    • 보안 문제들?
    • 익명화 문제가있는 데이터?
    • 완전히 자동화 할 수없는 스크립트?
  6. 프로세스를 탄력적이고 실행 가능하게 만드는 방법은 무엇입니까?
    • 개발자 오류?
    • 예기치 않은 환경 문제에?
    • 재해 복구를 위해?
  7. DB-SCM의 이점이 진정으로 비용을 정당화한다고 의사 결정권자들을 어떻게 설득합니까?
    • 일화적인 증거?
    • 산업 조사?
    • 업계 모범 사례 권장 사항?
    • 공인 된 당국에 항소합니까?
    • 비용 편익 분석?
  8. 이 모델에서 누가 데이터베이스 개체를 “소유”해야합니까?
    • 개발자?
    • DBA?
    • 데이터 분석가?
    • 하나 이상?


답변

다음은 질문에 대한 몇 가지 답변입니다.

  1. 테스트 및 프로덕션 환경 모두 소스 제어에서 구축해야합니까?
    • 둘 다 자동화를 사용하여 구축해야합니까? 아니면 안정적이고 최종화 된 테스트 환경에서 개체를 복사하여 구축해야합니까?
    • 둘 다 자동화. 환경간에 데이터를 복사하지 마십시오.
    • 배포 스크립트에서 테스트 환경과 프로덕션 환경 간의 잠재적 인 차이점을 어떻게 처리합니까?
    • 템플릿을 사용하여 실제로 각 환경에 대해 서로 다른 스크립트 세트를 생성 할 수 있습니다 (예 : 외부 시스템에 대한 참조, 연결된 데이터베이스 등).
    • 배포 스크립트가 테스트 에서처럼 프로덕션에 대해 효과적으로 작동하는지 어떻게 테스트합니까?
    • 사전 프로덕션 환경에서 테스트합니다. 프로덕션 환경의 정확한 사본 (데이터베이스 및 잠재적으로 다른 시스템)에서 배포를 테스트합니다.
  2. 어떤 유형의 객체를 버전 관리해야합니까?
    • 코드 (프로 시저, 패키지, 트리거, Java 등) 만 있습니까?
    • 인덱스?
    • 제약?
    • 테이블 정의?
    • 테이블 변경 스크립트? (예 : ALTER 스크립트)
    • 모두?
    • 모든 것, 그리고 :
      • 정적 데이터 (검색 목록 등)를 잊지 마세요. 따라서 환경간에 데이터를 복사 할 필요가 없습니다.
      • 현재 버전의 데이터베이스 스크립트 만 유지합니다 (물론 버전 제어).
      • ALTER 스크립트 저장 : BIG 스크립트 1 개 (또는 001_AlterXXX.sql과 같은 이름의 스크립트 디렉터리이므로 자연 정렬 순서로 실행하면 버전 A에서 B로 업그레이드 됨)
  3. 어떤 유형의 객체가 버전 제어되지 않아야합니까?
    • 시퀀스?
    • 보조금?
    • 사용자 계정?
    • 사용자 / 역할 (또는 기술 사용자 이름)이 환경마다 다른 경우에도 템플릿을 사용하여 스크립트를 작성할 수 있습니다 (1 참조).
  4. SCM 저장소에서 데이터베이스 개체를 어떻게 구성해야합니까?
    • 변환 스크립트 또는 ALTER 스크립트와 같은 일회성 작업을 어떻게 처리합니까?
    • 2 참조.
    • 데이터베이스에서 폐기되는 객체를 어떻게 처리합니까?
    • DB에서 삭제, 소스 제어 트렁크 / 팁에서 제거
    • 개체를 개발에서 테스트 수준으로 승격하는 책임자는 누구입니까?
    • 개발 / 테스트 / 출시 일정
    • 여러 개발자의 변경 사항을 어떻게 조정합니까?
    • 각 개발자에 대해 별도의 데이터베이스를 만들지 마십시오. 소스 제어를 사용하는 거죠? 이 경우 개발자는 데이터베이스를 변경하고 스크립트를 체크인합니다. 완전히 안전하려면 야간 빌드 중에 스크립트에서 데이터베이스를 다시 생성하십시오.
    • 여러 시스템에서 사용하는 데이터베이스 개체의 분기를 어떻게 처리합니까?
    • 힘든 일 : 어떤 대가를 치르더라도 피하십시오.
  5. 이 프로세스에 대해 어떤 예외가 합리적 일 수 있습니까?
    • 보안 문제들?
    • 테스트 / 프로덕션에 대한 암호를 저장하지 마십시오. 특히 매일 / 야간 DB 재 구축을 자동화 한 경우 개발자 용으로 허용 할 수 있습니다.
    • 익명화 문제가있는 데이터?
    • 완전히 자동화 할 수없는 스크립트?
    • 릴리스 정보 / ALTER 스크립트로 문서화 및 저장
  6. 프로세스를 탄력적이고 실행 가능하게 만드는 방법은 무엇입니까?
    • 개발자 오류?
    • 처음부터 일일 빌드로 테스트하고 결과를 증분 업그레이드 (ALTER를 사용하여 버전 A에서 B로)와 비교합니다. 결과 스키마와 정적 데이터를 모두 비교
    • 예기치 않은 환경 문제에?
    • 버전 제어 및 백업 사용
    • 특히 배포 전에 PROD 데이터베이스 스키마를 사용자가 생각하는 것과 비교합니다. SuperDuperCool DBA가 티켓 시스템에 없었던 버그를 수정했을 수 있습니다. 🙂
    • 재해 복구를 위해?
  7. DB-SCM의 이점이 진정으로 비용을 정당화한다고 의사 결정권자들을 어떻게 설득합니까?
    • 일화적인 증거?
    • 산업 조사?
    • 업계 모범 사례 권장 사항?
    • 공인 된 당국에 항소합니까?
    • 비용 편익 분석?
    • 개발자와 DBA가 동의하면 누구에게도 설득 할 필요가 없다고 생각합니다 ( MSSQL 용 dbGhost 와 같은 소프트웨어를 구입하는 데 돈이 필요하지 않은 경우 ).
  8. 이 모델에서 누가 데이터베이스 개체를 “소유”해야합니까?
    • 개발자?
    • DBA?
    • 데이터 분석가?
    • 하나 이상?
    • 일반적으로 DBA는 모델을 승인합니다 (체크인 전 또는 코드 검토의 일부로 후). 그들은 확실히 성능 관련 개체를 소유하고 있습니다. 그러나 일반적으로 팀이 소유하고 있습니다. [그리고 고용주, ​​물론 :)]

답변

가능한 경우 SQL을 소스 코드로 취급합니다.

표준 호환 SQL 로 작성할 수 있다면 일반적으로 소스 제어의 파일에 저장됩니다. 파일은 SP, Table CREATE 문과 같이 가능한 한 많이 정의합니다.

또한 소스 제어에서 테스트 할 더미 데이터를 포함합니다.

  1. proj / sql / setup_db.sql
  2. proj / sql / dummy_data.sql
  3. proj / sql / mssql_specific.sql
  4. proj / sql / mysql_specific.sql

그런 다음 모든 SQL 쿼리를 추상화하여 MySQL, Oracle, MSSQL 또는 기타를위한 전체 프로젝트를 빌드 할 수 있습니다.

빌드 및 테스트 자동화는 앱 소스만큼 중요한 이러한 빌드 스크립트를 사용 하고 무결성부터 트리거, 절차 및 로깅에 이르기까지 모든 것을 테스트합니다.


답변

TeamCity를 통한 지속적인 통합을 사용합니다. 소스 제어에 체크인 할 때마다 데이터베이스와 모든 테스트 데이터가 처음부터 다시 빌드되고 코드가 생성 된 다음 코드에 대해 단위 테스트가 실행됩니다. CodeSmith와 같은 코드 생성 도구를 사용하는 경우 빌드 프로세스에 배치하여 각 빌드마다 데이터 액세스 레이어를 새로 생성하여 모든 레이어가 “일치”하고 다음으로 인해 오류가 발생하지 않도록 할 수 있습니다. 일치하지 않는 SP 매개 변수 또는 누락 된 열.

각 빌드에는 소스 제어의 $ project \ SQL \ 디렉토리에 저장되고 숫자 접두사가 할당되고 순서대로 실행되는 고유 한 SQL 스크립트 모음이 있습니다. 이렇게하면 모든 빌드에서 배포 절차를 연습하고 있습니다.

조회 테이블에 따라 대부분의 조회 값도 스크립트에 저장되고 구성 데이터가 “reason_codes”또는 “country_codes”와 같이 예상 한 데이터인지 확인하기 위해 실행됩니다. 이렇게하면 가동 시간에 위험 할 수있는 프로덕션에서 조회 값을 수정하는 도구를 사용하는 대신 개발에서 조회 데이터를 변경하고 테스트 한 다음 QA 및 프로덕션을 통해 “승격”할 수 있습니다.

또한 프로덕션 빌드가 잘못 될 경우 데이터베이스 변경을 취소하는 “롤백”스크립트 세트를 만듭니다. 롤백 스크립트를 실행하여 테스트 한 다음 배포 스크립트가 실행 된 후 한 버전 아래의 빌드에 대한 단위 테스트를 다시 실행할 수 있습니다.


답변

+1 for Liquibase :
LiquiBase 는 데이터베이스 변경 사항을 추적, 관리 및 적용하기위한 오픈 소스 (LGPL)의 데이터베이스 독립적 라이브러리입니다. 이는 단순한 전제를 기반으로 구축됩니다. 모든 데이터베이스 변경 (구조 및 데이터)은 XML 기반 설명 방식으로 저장되고 소스 제어에 체크인됩니다. 좋은 점은 DML 변경 사항이 diff뿐만 아니라 의미 적으로 저장되므로 변경 목적을 추적 할 수 있다는 것입니다.

더 나은 상호 작용을 위해 GIT 버전 제어 와 결합 할 수 있습니다 . 나는 그것을 시도하기 위해 우리의 dev-prod 환경을 구성 할 것입니다.

또한 Maven, Ant 빌드 시스템을 사용 하여 스크립트에서 프로덕션 코드를 빌드 할 수 있습니다 .

그쪽으로 빼면 LiquiBase는 광범위한 SQL IDE에 통합되지 않으며 기본 작업을 직접 수행해야합니다.

이 외에도 DB 테스트를 위해 DBUnit 을 사용할 수 있습니다. 이 도구를 사용하면 데이터 생성 스크립트를 사용하여 나중에 정리하여 프로덕션 환경을 테스트 할 수 있습니다.

IMHO :

  1. 버전을 지정할 수 있도록 DML을 파일에 저장합니다.
  2. 소스 제어에서 스키마 빌드 프로세스를 자동화합니다.
  3. 테스트 목적으로 개발자는 빌드 시스템을 통해 소스 제어에서 빌드 된 로컬 DB를 사용하고 스크립트로 데이터를로드하거나 DBUnit 스크립트 (소스 제어에서)를 사용할 수 있습니다.
  4. LiquiBase를 사용하면 종속성을 고려하여 스크립트의 “실행 순서”를 제공 할 수 있습니다.
  5. 프로덕션 사용 전에 모든 변경 사항으로 마스터 브런치를 확인하는 DBA 팀이 있어야합니다. 나는 그들이 MASTER 트렁크에 커밋하기 전에 다른 DBA의 트렁크 / 분기를 확인한다는 것을 의미합니다. 따라서 마스터는 항상 일관성 있고 생산 준비가되어 있습니다.

우리는 청구 프로덕션 데이터베이스에서 코드 변경, 병합, 재 작성과 관련하여 언급 된 모든 문제에 직면했습니다. 이 주제는 모든 것을 발견하는 데 유용합니다.


답변

“티저 질문”을함으로써 최종 답변에 대한 누군가의 의견보다 토론에 더 관심이있는 것 같습니다. 활발한 (2500 명 이상의 회원) 메일 링리스트 인 agileDatabases 는 이러한 많은 질문을 다루었으며 제 경험상 이러한 종류의 토론을위한 정교하고 시민적인 포럼입니다.


답변

나는 기본적으로 van이 제공하는 모든 대답에 동의합니다 . 더 많은 통찰력을 위해 데이터베이스 관리에 대한 기준은 K. Scott Allen 시리즈입니다 (필독해야 할 사항, IMHO. Jeff의 의견 도 그렇습니다).

  • 데이터베이스 객체는 항상 단일 SQL 파일 (다른 SQL 파일을 호출 할 수 있음)을 실행하여 처음부터 다시 작성할 수 있습니다 Create.sql.. 여기에는 정적 데이터 삽입 (목록 …) 이 포함될 수 있습니다 .
  • SQL 스크립트는 매개 변수화되어 환경 의존적 및 / 또는 민감한 정보가 일반 파일에 저장되지 않습니다.
  • 나는 발사에 사용자 지정 배치 파일을 사용 Create.sql: Create.cmd. 그 목적은 주로 전제 조건 (도구, 환경 변수 …)을 확인하고 매개 변수를 SQL 스크립트로 보내는 것입니다. 성능 문제를 위해 CSV 파일에서 정적 데이터를 대량로드 할 수도 있습니다.
  • 일반적으로 시스템 사용자 자격 증명은 Create.cmd파일에 매개 변수로 전달됩니다 .

IMHO, 동적 데이터로드에는 환경에 따라 다른 단계가 필요합니다. 개발자는 테스트, 정크 또는 데이터 없음으로 데이터베이스를로드하고 다른 최종 프로덕션 관리자는 프로덕션 데이터를로드하려고합니다. 예를 들어 단위 테스트를 쉽게하기 위해 소스 제어에 테스트 데이터를 저장하는 것도 고려할 것입니다.

데이터베이스의 첫 번째 버전이 프로덕션에 배치되면 빌드 스크립트 (주로 개발자 용)뿐만 아니라 업그레이드 스크립트 (동일한 원칙에 따라)도 필요합니다.

  • 데이터베이스에서 버전을 검색하는 방법이 있어야합니다 (저장 프로 시저를 사용하지만 테이블도 가능합니다).
  • 새 버전을 릴리스하기 전에 Upgrade.sql버전 N-1을 버전 N (N은 릴리스되는 버전)으로 업그레이드 할 수 있는 파일 (다른 버전을 호출 할 수 있음)을 만듭니다. 이 스크립트는라는 폴더에 저장합니다 N-1.
  • 업그레이드를 수행하는 배치 파일이 Upgrade.cmd있습니다. 간단한 SELECT 문을 통해 데이터베이스의 현재 버전 (CV)을 검색하고 Upgrade.sql, CV폴더 아래에 저장된 스크립트를 시작하고 , 폴더를 찾을 수 없을 때까지 반복 할 수 있습니다. 이렇게하면 N-3에서 N으로 자동 업그레이드 할 수 있습니다.

이 문제는 다음과 같습니다.

  • 데이터베이스 공급 업체에 따라 데이터베이스 스키마를 자동으로 비교하는 것은 어렵습니다. 이로 인해 불완전한 업그레이드 스크립트가 발생할 수 있습니다.
  • 프로덕션 환경에 대한 모든 변경 (일반적으로 성능 조정을 위해 DBA에 의해)은 소스 제어에도 적용되어야합니다. 이를 확인하기 위해 일반적으로 트리거를 통해 데이터베이스에 대한 모든 수정 사항을 기록 할 수 있습니다. 이 로그는 업그레이드 할 때마다 재설정됩니다.
  • 하지만 더 이상적으로는 DBA가 시작한 변경 사항이 가능하면 릴리스 / 업그레이드 프로세스의 일부가되어야합니다.

소스 제어하에 어떤 종류의 데이터베이스 개체를 갖고 싶습니까? 글쎄, 나는 가능한 한 많이 말하고 싶지만 😉 암호로 사용자를 만들고 싶다면 기본 암호 (로그인 / 로그인, 단위 테스트 목적에 실용적)를 얻고 암호 변경을 수동 작업으로 만듭니다. . 이것은 스키마도 사용자 인 Oracle에서 많이 발생합니다.


답변

Git 버전 제어에 MSSQL 데이터베이스가 포함 된 Silverlight 프로젝트가 있습니다. 가장 쉬운 방법은 얇아진 데이터베이스 (콘텐츠 측면)가 있는지 확인 하고 fe Visual Studio에서 전체 덤프를 수행하는 것 입니다. 그런 다음 빌드 스크립트에서 ‘sqlcmd’를 수행하여 각 dev 컴퓨터에서 데이터베이스를 다시 만들 수 있습니다.

배포의 경우 데이터베이스가 너무 크기 때문에 불가능합니다. 이것이 데이터베이스에있는 주된 이유입니다.