데이터 유효성 검사를 지원하는 ORM의 경우 데이터베이스에도 제약 조건이 적용되어야합니까?


13

내 (ActiveRecord) 모델 외에도 데이터베이스 수준에서 제약 조건을 항상 적용했습니다. 그러나 이것이 정말로 필요한지 궁금합니다.

작은 배경

최근에 모델에 대한 기본 자동 타임 스탬프 생성 방법을 단위 테스트해야했습니다. 일반적으로 테스트는 모델의 인스턴스를 작성하고 유효성 검증없이 저장합니다. 그러나 테이블 정의에서 null을 허용하지 않는 다른 필수 필드가 있으므로 ActiveRecord 유효성 검사를 건너 뛰더라도 인스턴스를 저장할 수 없습니다. 그래서 db 자체에서 그러한 제약 조건을 제거하고 ORM이 처리하도록해야하는지 생각하고 있습니다.

db, imo에서 제약 조건을 건너 뛰면 가능한 이점

  • 데이터베이스를 마이그레이션하지 않고도 모델에서 유효성 검사 규칙을 수정할 수 있습니다.
  • 테스트에서 유효성 검사를 건너 뛸 수 있습니다.

가능한 단점?

ORM 유효성 검증이 실패하거나 무시 될 수있는 경우 데이터베이스는 제한 조건을 점검하지 않습니다.

어떻게 생각해?

편집 이 경우 데이터베이스에서 모델을 생성 하는 Yii Framework를 사용하고 있으므로 데이터베이스 규칙도 생성됩니다 (생성 후 항상 직접 작성할 수도 있음).


3
ORM을 사용하지 않고 데이터베이스의 데이터를 일상적으로 수정할 수있는 경우 (ORM이없는 다른 앱 또는 사용자가 직접 DB에 직접 액세스) 유효성 검사는 실제로 데이터베이스에 있어야합니다.
Marjan Venema 2016 년

답변:


16

당신의지도 원리는 스스로 반복하지 말아야합니다 :

소프트웨어 엔지니어링에서 DRY (Do n't Repeat Yourself)는 모든 종류의 정보 반복을 줄이고 특히 다중 계층 아키텍처에 유용한 소프트웨어 개발 원칙입니다. DRY 원칙은 "모든 지식은 시스템 내에서 하나의 명백하고 권위있는 표현을 가져야한다"고 명시되어 있습니다.

ORM은 본질적으로 응용 프로그램과 데이터 저장소 사이에 편안하게 앉아있는 추가 계층 (또는 원하는 경우 계층)입니다. 제약 조건은 ORM 또는 데이터 저장소 와 같은 한 곳에 있어야하며 , 그렇지 않으면 머지 않아 다른 버전을 유지 관리하게됩니다. 당신은 정말로 그렇게하고 싶지 않습니다.

그러나 실제로 대부분의 절반 정도의 ORM은 자동으로 데이터 스키마에서 많은 모델을 생성합니다. 여전히 중복이 있지만 중복 된 ORM 코드가 매번 동일한 패턴에 따라 생성되므로 유지 보수의 가능성이 최소화됩니다. 중복 코드가없는 것이 이상적이지만 자동으로 생성 된 제약 조건이 차선책입니다.

또한 한 곳에서 제약 조건 이 있다고해서 반드시 모든 제약 조건이 같은 장소에 있어야한다는 의미 는 아닙니다 . 참조 무결성 제한 조건과 같은 일부는 데이터 스토리지에 더 적합 할 수 있지만 (다른 데이터 스토리지로 이동하면 손실 될 수 있음) 일부는 대부분 복잡한 비즈니스 로직에 관한 것이 ORM에 더 적합합니다. 모든 사과를 같은 바구니에 두는 것이 바람직하지만…

실패

당신은 ORM 실패를 언급합니다. 그것은 귀하의 질문과 전혀 관련이 없으며, 응용 프로그램은 ORM과 데이터 저장소를 단일 엔티티로 생각해야합니다. 실패하면 실패하고 ORM을 우회하여 데이터 스토리지와 직접 대화하는 것은 좋지 않습니다 .

다른 것을 위해 ORM을 우회

또한 좋은 생각이 아닙니다. 그러나 여러 가지 이유로 발생할 수 있습니다.

  1. ORM이 도입되기 전에 작성된 응용 프로그램의 레거시 부분.

    그것은 힘든 일이며, 지금 당장 다루고있는 상황 이므로,“지속적인 지옥”에 대한 끊임없는 반복입니다. 비 ORM 부품을 계속 유지하거나 ORM을 사용하도록 다시 작성하십시오. 두 번째 옵션 처음에는 더 의미가 있지만, 애플리케이션의 해당 부분에서 정확히 수행하는 작업과 장기적으로 전체 재 작성의 가치에 따라 결정됩니다.

    잘못 설계된 2 * 10 ^ 8 행 MySQL 테이블에서 키를 변경해보십시오 (다운 타임 없음). 내가 어디에서 왔는지 이해할 수 있습니다.

  2. 데이터 스토리지와 직접 통신해야하는 비 레거시 애플리케이션 부분 :

    더 까다 롭습니다. ORM은 멋진 도구이며 거의 모든 것을 처리하지만 때로는 방해가되거나 전혀 쓸모가 없습니다. Buzzword (실제로 Buzzphrase)는 객체 관계형 임피던스 불일치 입니다. ORM이 관계형 데이터베이스가 수행하는 모든 작업을 기술적으로 불가능하게 만드는 것은 불가능합니다 .

코멘트

데이터 무결성의 관점에서 제약 조건은 반드시 데이터베이스에 있어야하고 애플리케이션에 있어야합니다. 웹 및 데스크톱 응용 프로그램, 모바일 응용 프로그램 또는 웹 서비스에서 응용 프로그램에 액세스하면 어떻게됩니까? – 루이즈 담

여기에 여분의 레이어를 추가하는 것이 매우 도움이되는 곳이며, 웹 애플리케이션에 대해 이야기하는 경우 REST API를 사용합니다. 지나치게 단순한 디자인 이에 대한은 다음과 같습니다

여기에 이미지 설명을 입력하십시오

ORM은 API와 데이터 스토리지 사이에 있으며 API 뒤의 모든 것 (이를 포함하여)은 다양한 애플리케이션에서 단일 엔티티로 간주됩니다.


일반적으로 ORM에서 스키마를 정의한 다음 데이터베이스에 미러링하여 두 번째 수준의 보증을받습니다.
Josh K

2
@JoshK 당신은 두 번째 수준의 보증을 말합니다. 당신이 옳지 않다고 말하지는 않지만 ...
yannis

말이된다. 나는 지금이 길을 따르고있다. 감사!
na

1
한두 명의 개발자가 코드 데이터베이스 작업을 수행하는 지점을 지나면 필요한 악이됩니다. 좋은 ORM을 사용하면 마이그레이션도 생성됩니다. 전용 DBA를 보유한 지점으로 성장할 때 그 방법은 없지만 제약 조건없이 테이블을 띄울 수는 없습니다. 이메일없이 사람들이 가입하지 못하도록하는 간단한 방법은 저장소 수준을 제한하는 것입니다.
Josh K

1
데이터 무결성의 관점에서 제약 조건은 반드시 데이터베이스에 있어야하고 애플리케이션에 있어야합니다. 웹 및 데스크톱 응용 프로그램, 모바일 응용 프로그램 또는 웹 서비스에서 응용 프로그램에 액세스하면 어떻게됩니까?
Luiz Damim 2016 년

20

이것은 실제로 대답하기 매우 어려운 질문이며 매우 논란의 여지가있는 주제라는 것을 알았습니다.

Yannis Rizos가 자신의 답변에서 지적한 것처럼 데이터베이스와 ORM 계층 모두에 제약 조건 논리가 DRY를 위반하는 것 같습니다.

그러나 다음 조건 중 하나가있는 경우 데이터베이스에서 제한 조건 논리를 제거하고 ORM 계층에서만 유지하면 작동하지 않습니다.

  1. 수동 DB 업데이트 (모든 회사에서 발생하는 것으로 보입니다)

  2. ORM 제약 조건 로직을 항상 쉽게 공유 할 수없는 다른 시스템의 DB 업데이트 (예 : ORM 계층이 Hibernate에서 구현되고 일상적인 활동을 위해 Java 응용 프로그램에서 사용될 때 일상적인 작업을 수행하는 Perl 스크립트)

이는 DRY 위반을 방지하기 위해 제약 조건 논리를 DB에 추가하고 ORM 계층 에서 제거하는 것만 제안합니다 . 그러나 이로 인해 응용 프로그램 코드가 실제 문제를 성공적으로 캡처하여 사용자에게 전달할 수없는 경우가 발생할 수 있습니다 (개발자가 문제를 디버깅 할 때 가능할 수 있음). 일부 프로젝트에서는 허용되지 않을 수 있습니다.

마지막 옵션은 DB 제약 조건 (또는 실제로는 그 반대의 경우)에서 ORM (및 다른 시스템)에 제약 조건 생성자동화하는 것 입니다. 결국 두 가지 이상의 제약 조건 구현으로 끝나더라도 DRY 위반을 피하기 위해 코드 생성의 활용을 권장하므로 "실용적인 프로그래머"에 설명 된대로 DRY 원칙을 위반하지 않습니다. 물론, 예를 들어 DB 제약 조건을 변경할 때마다 자동으로 사소한 것이 아니라 DB 제약 조건을 사용하는 모든 응용 프로그램을 다시 빌드하고 다시 배포해야 할 수 있기 때문에 그렇게 간단하지 않습니다.

실제로 사례별로 평가해야합니다 . 구속 점 논리를 반복하지 말 것을 제안 할 때이 시점에서 나는 빈 쳐다보기를 만났다고 말할 수 있습니다.


2
방금 일을 마치고 방금 게시 한 내용으로 내 대답을 확장하려고 생각했습니다. 좋은 대답입니다!
yannis 2016 년

3

기본 옵션으로 데이터베이스에 제약 조건을 추가합니다. 이는 엔터프라이즈 데이터가 왕이고 데이터 품질이 가장 중요하기 때문입니다. @Yannis Rizos는 DRY 원칙을 토론에 가져 왔습니다. 또 다른 원칙은 심층 방어입니다. 데이터에는이 원칙을 사용합니다.

저는 30 년 전에 DB에 데이터를 생성 한 실제 기업에서 근무했습니다. COBOL 응용 프로그램 및 .Net 응용 프로그램에 의해 여전히 액세스되었습니다. 10 년 후 벤더 앱일지도 모른다. 합병이 있었으며 수백만 행의 데이터가 SQL을 사용하여 다른 회사에서이 데이터베이스로 변환 및 마이그레이션되었습니다. 어떤 ORM도이 작업을 수행 할 수 없습니다. 결론은 데이터가 남아 있고 응용 프로그램이 변경되고 데이터가 생성되는 방식입니다. 그렇다면 데이터 손상 가능성을 줄이십시오.


2

나는 당신이 어느 정도를 수행한다고 생각합니다.

  • 기본 제약 조건은 ORM에 있어야합니다. 프로그래밍 언어는 훨씬 더 유연하며 요구 사항이 변경 될 때 테스트하기가 쉽고 조정이 쉽습니다. 최소한 DDL 수정에 대해 걱정할 필요가 없습니다. 또한 일반적으로 데이터 회귀 문제를 테스트하기가 어렵습니다.

  • 매우 어렵고 빠른 제약 조건도 데이터베이스에 존재해야합니다. 예를 들어 nullable이 아닌 이름에 대해서는 이야기하지 않습니다. 참조 무결성 또는 절대적으로 중요한 식별자가 필요한 것에 대해 이야기하고 있습니다. 코드가 "주문에 존재하지 않는 제품이있는 경우"를 처리 할 필요가없는 구조적 요구 사항.


1

데이터베이스가 IMO는 DRY를 위반할 수있는 유일한 장소입니다. ORM을 우회하고 데이터가 나쁜 경우 그게 전부입니다. 게임 끝. 손상된 데이터가있는 것은 치명적인 타격입니다.


데이터베이스 만? 데이터와 관련된 동작이 데이터가 전혀 유지되지 않더라도 여러 계층 (논리적 또는 물리적)에 존재해야하는 경우를 많이 생각할 수 있습니다. 때로는 단일 소스 코드를 사용하여 배포 된 dll에 대한 "중복"을 줄일 수 있습니다.
mike30
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.