관계형 데이터베이스 및 반복 개발


19

민첩한 방법론, 도메인 중심 설계 및 객체 지향 분석 및 설계와 같은 소프트웨어 개발에 대한 많은 접근 방식에서 개발에 반복적 인 접근 방식을 사용하는 것이 좋습니다.

따라서 우리는 프로젝트에서 처음 작업을 시작할 때 도메인 모델을 완성하지 않아야합니다. 대신 시간이 지남에 따라 시간이 지남에 따라 문제 영역을 더 깊이 이해하기 때문에 모델을 리팩터링합니다.

그 외에도, 우리가 이미 완벽하다고 확신하는 완벽한 모델을 미리 만들려고해도 요구 사항이 변경 될 수 있습니다. 따라서 소프트웨어 프로덕션 환경에 배포 된 후 최종 사용자는 특정 요구 사항을 완전히 이해하지 못했거나 일부 요구 사항이 누락 된 것을 알 수 있습니다.

여기서 요점은 소프트웨어가 배포 된 후 모델을 변경해야 할 수도 있다는 것입니다. 이런 일이 발생하면 문제가 생깁니다. 프로덕션 데이터베이스 에는 중요하고 이미 이전 모델의 형식으로 적합한 사용자 데이터가 있습니다 .

코드가 제대로 설계되지 않았고 시스템이 큰 경우 코드 업데이트가 어려운 작업 일 수 있습니다. 그러나 시간이 지남에 따라 할 수 있습니다. Git과 같은 도구가있어 프로덕션 준비 버전을 손상시키지 않고 그렇게 할 수 있습니다.

반면, 모델이 변경되거나 클래스의 속성이 사라지거나 데이터베이스가 변경되는 경우 데이터베이스도 변경되어야합니다. 그러나 우리는 문제가 있습니다 : 이미 잃어 버릴 수없는 데이터가 있으며 이전 모델에 맞게 이미 형식화되었습니다.

여기의 관계형 데이터베이스는 최종 사용자가 필요할 때 반복 개발을 수행하고 소프트웨어를 업데이트하지 못하게하는 장벽 인 것 같습니다.

내가 이미 사용한 한 가지 접근법은 오래된 데이터베이스 테이블을 새로운 데이터베이스 테이블로 매핑하는 특수 클래스를 코딩하는 것이 었습니다. 따라서이 클래스는 이전 형식의 데이터를 선택하여 새 모델에서 사용하는 형식으로 변환 한 후 새 테이블에 저장합니다.

이 방법은 최선의 방법이 아닌 것 같습니다. 내 질문은 여기에 있습니다 : 관계형 데이터베이스와 반복 개발을 조정하기 위해 잘 알려져 있고 권장되는 접근법이 있습니까?


6
덧붙여서, 나는 이것이 특히 관계형 데이터베이스 와 관련 이 있다고 생각하지 않습니다 . 작업중 인 프로젝트와 비슷한 문제가 있지만 관계형이 아닌 객체를 나타내는 JSON 문자열의 스키마에 문제가 있습니다. 아마도 모든 형태의 지속성에 똑같이 영향을 미칩니다.
Ixrec

1
데이터를 잃지 않는 방식으로 데이터베이스 스키마를 변경하십시오 ( en.wikipedia.org/wiki/Schema_migration) .
RemcoGerlich 2019

1
나는이 주제가 전에 어딘가에서 광범위하게 논의되었다고 확신합니다. 프로그래머에서는 찾을 수 없습니다. 그러나 여기에서 martinfowler.com/articles/evodb.html 또는 여기를보십시오 stackoverflow.com/questions/334059/…
Doc Brown

1
"그 외에도, 우리가 이미 완벽한 모델을 선구하려고하더라도 매우 어렵다고 생각하면 요구 사항이 바뀔 수 있습니다." 나는 당신이 (완벽에 가까운) 모델을 선발하려고 시도해서는 안된다고 덧붙이고 싶습니다. 옵션을 열어 두지 않고 사고 방식을 한 가지 유형의 솔루션에 묶을 수 있습니다.
벤트

답변:


15

특별한 클래스 일 필요는 없지만 예, 데이터베이스를 이전 형식으로 가져 와서 현재 형식으로 변환 할 무언가가 필요합니다.

여기서는 수동으로 테스트 및 프로덕션 데이터베이스를 건드리지 않고 항상 마이그레이션 스크립트를 사용하여 이러한 스크립트와 규칙을 작성하고 테스트하는 프로세스를 개발해야합니다.

데이터베이스를 변경해야 할 때마다 SQL이든 ORM 계층을 사용하든 상관없이 스크립트를 작성하여 새 스키마가 필요한 변경 사항과 함께 버전 제어에 커밋하십시오. 그런 다음 아직 적용되지 않은 모든 마이그레이션 스크립트를 순서대로 적용하여 데이터베이스를 업그레이드하는 제어 스크립트가 있습니다.

또한 스크립트를 적용하고 작동하지 않는 경우 이전 버전으로 롤백하여 공유 개발, 테스트 및 QA 환경 만 수정해야합니다. 따라서 프로덕션 환경에서 스크립트를 공개 할 때 의도 한대로 작동 할 것이라고 확신 할 수 있습니다. .

모든 스크립트를 적용하면 간단하게 새로 설치할 수 있습니다. 시간이 지나면 수백 가지를 가질 수 있으며 비효율적이라고 생각하지만 최적화하려고 함정에 빠지지 마십시오. 설치는 일회성이며 신뢰할 수있는 성능을 유지하면서 빠르게 진행됩니다.

@Doc 브라운은 이미 연결된 마틴 파울러 : 진화 데이터베이스 설계/programming/334059/agile-development-and-database-changes을 , 내가 추가 할 것 알렉스 Papadimoulis을 : 데이터베이스를 마우스 오른쪽 단추로 변경된 사항 짧은, 몇 가지 예가 있습니다.

그러한 프로세스를 구현하는 툴의 좋은 예로써 나는 Alembic을 제안 한다 . Python SQLAlchemy 프레임 워크를 기반으로 하지만 자체 마이그레이션 지원이없는 다른 언어 및 프레임 워크와 함께 사용할 수 있습니다. Schema Migration 의 Wikipedia 페이지 에는 더 많은 도구가 나열되어있다 .


1
@Tibo 동일한 시퀀스의 스크립트를 실행하여 스키마를 처음부터 작성합니다. 이것이 문제를 관리하는 방법입니다. 표준으로 볼 때 아직 존재하지 않는 데이터베이스를 포함하여 모든 데이터베이스 인스턴스에서 현재 스키마로 가져올 수 있으며 동일하다는 확신을 가질 수 있습니다. 귀하의 예에 따라 두 가지 방법이 필요하지 않습니다. (적어도 일관된 기준선이 제공되지 않음-첫 번째 단계는 기준선을 설정하고 일단 해당 기준선에 도달하면 문제가 사라집니다.)
Murph

1
Alex의 기사에 대해서는 추천합니다. 더 짧지는 않지만 실용적이고 재미있는 읽기를 제공합니다.
Murphy

1
우리는 민첩한 상점이고 100 % 가동 시간 서비스를 운영하며이 두 가지 모두 DB에도 적용됩니다. 우리는 하루에 한 번 평균 생산 스키마를 마이그레이션하며 Jan이 말한 모든 것을 두 번째로 할 것입니다. 우리가 귀중한 한 가지 추가 작업은 마이그레이션 테스트라고하는 것입니다. 이는 빌드 및 배포 프로세스의 일부로 실행됩니다. 스키마 스냅 샷을 프로덕션에서 해제하고 보류중인 마이그레이션을 마스터에서 마스터로 마이그레이션 한 다음 현재 배포 된 프로덕션 코드에서 해당 스키마에 대해 단위 테스트를 실행합니다. 마이그레이션을 적용해도 실행중인 시스템이 중단되지 않는지 확인하는 것이 목표입니다.
고든 리글리

1

이상하게도, 이것은 현재 개발 팀이 직면 한 매우 문제입니다. 이 질문에는 여러 가지 하위 질문이 포함되어 있으므로 독립적으로 다루게됩니다.

무엇보다도 관계형 데이터베이스는 데이터 모델을 너무 많이 제한하여 변경을 매우 어렵게합니까?

가장 확실한 것은 아니지만 반드시 언급 된 이유 일 필요는 없습니다. 불행히도, 관계형 데이터베이스 관리 시스템의 다양성은 또한 붕괴로 이어집니다. RDBMS는 원래 큰 데이터 세트를 수용하고 상대적으로 작은 크기로 줄일 수있는 비교적 간단한 데이터 스토리지 플랫폼을 제공하도록 개발되었습니다. 이는 데이터 모델의 복잡성과 필요한 계산 능력을 희생하여 수행되었습니다. 데이터베이스 복잡성이 증가함에 따라 저장 프로 시저, 뷰, 기능 및 트리거는 데이터베이스 관리자가 일관성 있고 확장 가능한 방식으로 복잡성을 처리 할 수 ​​있도록 도와주었습니다.

불행하게도, 관계형 데이터베이스 모델은 객체 지향적이지 않으며 데이터 모델처럼 실제 엔티티에 자연스럽게 맵핑되지 않습니다. 따라서 객체 관계형 매퍼 등과 같은 중개 도구가 필요합니다. 불행하게도, 이러한 도구는 오늘날의 개발 환경에서 분명히 자리 잡고 있지만, 그 사용은 데이터 모델이 실제 세계에 맞지 않는 근본적인 원인이 아니라 관계형 데이터 복잡성 문제의 증상을 목표로합니다.

그것은 질문의 두 번째 부분으로 이어지는데, 이것은 실제로 더 많은 가정 이었지만 질문으로보아야 합니다. 우리는 도메인 모델을 처음으로 올바르게 수행해야합니까?

그렇습니다. 문제가 지적했듯이 디자인 프로세스를 시작할 때 문제를 완전히 이해하는 것은 거의 불가능합니다. 그러나 도메인에 대한 이해가 높아짐에 따라 조정될 수있는 데이터 모델과 달리 완전히 잘못된 데이터 모델의 차이점은 현실 세계에 일관성있게 매핑되는 모델입니다. 즉, 실제 실체의 관점에서 문제에 대한 이해와 일치하는 초기 데이터 모델을 작성하기 위해 모든 노력을 기울여야합니다. 잘못된 엔터티를 정규화하기 시작하면 데이터 모델이 두 가지 방식으로 잘못되어 복구가 어려워집니다.

여러 가지면에서 "No SQL"데이터베이스 솔루션으로의 이동은 데이터 모델 불일치 문제의 결과입니다. 객체 지향 활용 SQL을 사용하지 않는 접근 방식을 사용하면 코드에서 객체와 실제 객체 간의 매핑에 대해 더 많이 생각하게되며, 불일치가 발생하면 구현할 수 없기 때문에 자명합니다. 데이터 베이스. 이것은 전반적인 디자인을 향상시킵니다.

그것은 마지막 질문으로 이어진다 : 관계형 데이터 모델이 민첩한 접근 방식과 일치하지 않는가?

아니요,하지만 더 많은 기술이 필요합니다. No-SQL 환경에서는 필드를 추가하거나 속성을 배열로 변환하는 것이 쉽지 않지만 관계형 환경에서 이러한 작업을 수행하는 것은 결코 쉬운 일이 아닙니다. 관계형 데이터 모델과 이들이 나타내는 실제 엔터티를 모두 이해할 수있는 사람이 최소한 필요합니다. 이 사람은 실제 모델 변경에 대한 이해로 관계형 모델 업데이트를 용이하게하는 개인입니다. 이 문제를 해결하기 위해은 총알이 없습니다.


1
RDBMS 테이블에 새 필드를 작성하여 문제를 더욱 극명하게 만들기 위해 큰 문제가되기를 정말로 바랍니다. 하나의 필드를 추가하는 데 실제로 문제점을 발생 시키려면 데이터베이스 테이블이 매우 특별해야합니다 (또는 새 필드 유형이 예외적이어야 함).
Alexey Zimarev

그렇습니다, 그러나 그것은 단지 하나의 필드가 아닙니다 ...
theMayer

1
더 자주 말하면 하나의 필드 일뿐입니다. 극적인 스키마 변경은 그다지 자주 이루어지지 않습니다. 임피던스 불일치로 인해 OO 디자인의 RDBMS를 사용하는 팬이 아닙니다. 그러나 NoSQL에서는 실제로 조금 더 쉽지만 새로운 유형 (테이블)과 속성 (열)을 추가하는 것은 두 세계에서 비교적 쉽습니다. 그러나 복잡한 변화는 두 경우 모두 고통입니다. 더 나쁜 것은 이러한 시스템의 개발 경험이 얼마나 즐거운 지에 반해 스냅 샷이있는 이벤트 소스 시스템에서 더 악화됩니다.
Alexey Zimarev

관계형 데이터베이스는 데이터 저장소 요구를 해결하기 위해 "유니버설 해머"로 사용되는 경우가 많습니다. 실제로 사용하는 데 특별한 이유가 있습니다. 신중하게 고려 된 시스템에서는 내가 대답 할 때 쓴 문제에 대해 거의 걱정할 필요가 없습니다. 적절한 시스템 디자인을 미리 경험 한 경험이없는 일반 사용자를 대상으로합니다.
theMayer

관계형 모델 간에는 불일치가 없으며 일반적으로 다른 유형의 모델뿐만 아니라 실제 세계에도 매핑됩니다. 어떤 종류의 작업은 다른 종류의 작업에서는 더 쉬울 수 있습니다. 문제는 한 종류의 모델 (객체 지향)을 만들고 다른 종류의 도구 (관계형)로 구현하려고 할 때 발생합니다. 그것은 잘 작동하지 않습니다. 그러나 현실 세계는 객체 지향적이지 않다. 그냥 있고 당신은 그것을 모델링합니다. 선택한 종류의 모델에 적합한 도구를 사용해야합니다.
Jan Hudec

-1

요점은 리팩토링을 너무 많이하여 모델이 모든 인식 범위를 넘어서서 변화하는 것입니다. 반복적 인 개발에도 불구하고 실제로 기존 항목을 기반으로 구축하고 조각으로 리팩토링하지 않아야합니다.

이를 통해 큰 변화를 처리 할 수있는 두 가지 주요 옵션이 제공됩니다. 첫 번째는 DB 레이어를 API로 구축하고 저장 프로 시저를 사용하여 기본 데이터 스키마를 변경하지 않고 클라이언트에 맞게 변경할 수 있습니다.

다른 방법은 테이블을 약간의 데이터 마이그레이션으로 바꾸는 것입니다. 대규모 변경이 필요한 경우 새 스키마를 작성하고 스크립트 세트를 구현하여 이전 데이터를 가져 와서 새 형식으로 마사지하십시오. 이를 수행하는 데 시간이 걸리기 때문에 데이터 액세스를 수정하는보다 저렴한 방법 (예 : SP 등)을 우선적으로 선택해야합니다.

따라서 : 1. 디자인을 미리 생각하여 변경하지 않아도됩니다.

  1. 랩퍼 또는 API에 의존하므로 변경이 제한되거나 격리 된 구성 요소 내에 숨겨 질 수 있습니다

  2. 필요한 경우 시간을내어 제대로 업그레이드하십시오.

이 단계는 데이터베이스뿐만 아니라 모든 것에 적용됩니다.


기본 체계 를 변경 해야하는 경우 있습니다. 응용 프로그램이 고객 테스트를 시작함에 따라, 전혀 들어 보지 못한 새로운 속성이 자라며, 숫자라고 생각한 속성은 문자열로 판명되었으며, 1 : 1로 예상되는 관계는 결국 그렇게되지 않을 것입니다. 저장 프로 시저 뒤에있는 이런 종류의 작업은 다루지 못합니다 (저장 프로시 저는 데이터베이스의 다른 작업과 마찬가지로 버전 제어 기능이 없으므로 저장 프로시 저는 문제의 일부입니다).
Jan Hudec

SP는 언제 버전 제어에 포함되지 않습니까? 그러한 것들을 다룰 수 있습니다 .SP API를 변경하여 문자열을 가져 와서 다른 필드에 쓰면 SP의 코드에서 이전 숫자와 새 문자열을 처리합니다. 가장 좋은 것은 아니지만 모든 고객 사이트를 방문하여 데이터를 새로운 문자열 형식으로 마이그레이션하는 것보다 낫습니다 (더 나은 예제가 있지만 아이디어를 얻습니다). 변경이 큰 것으로 밝혀지면 마이그레이션해야하지만 적어도 DB API를 사용하면 더 저렴하고 다른 옵션도 있습니다.
gbjbaanb

SP를 설치하고 새 필드를 추가하려면 각 고객 사이트로 이동해야합니다. 그리고 거기에 있으면 데이터도 마이그레이션 할 수 있습니다. SP는 여러 응용 프로그램이 데이터베이스에 액세스하는 경우 이전 버전과 호환되는 인터페이스를 만들 수 있으므로 모든 응용 프로그램을 동시에 업그레이드 할 필요가 없다는 점에서 유용합니다. 그러나 요구 사항 변경으로 인해 스키마를 변경해야 할 경우 단계를 저장하지 않습니다.
Jan Hudec
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.