데이터베이스에서 잘못된 널 항목을 방지하기위한 설계 및 실습


9

내 프로그램의 한 부분은 처리를 위해 데이터베이스의 많은 테이블과 열에서 데이터를 가져옵니다. 일부 열은 null이지만 현재 처리 컨텍스트에서 오류 일 수 있습니다.

이것은 "이론적으로"일어나지 않아야하는데, 그렇게된다면 그것이 나쁜 데이터 나 코드의 버그를 가리 킵니다. 어떤 필드가 어떤지에 따라 오류의 심각도가 다릅니다 null. 즉, 일부 필드의 경우 처리를 중지하고 누군가에게 통지해야합니다. 다른 필드의 경우 처리를 계속하고 누군가에게 알리는 것이 허용되어야합니다.

드물지만 가능한 null항목 을 처리하기위한 좋은 아키텍처 또는 디자인 원칙이 있습니까?

솔루션은 Java로 구현할 수 있어야하지만 문제는 언어에 구애받지 않는다고 생각하기 때문에 태그를 사용하지 않았습니다.


내가 가진 생각은 다음과 같습니다.

NOT NULL 사용

데이터베이스에서 NOT NULL 제약 조건을 사용하는 것이 가장 쉽습니다.

그러나 데이터의 원래 삽입이 나중에 처리 단계보다 더 중요하다면 어떻게해야합니까? 따라서 삽입 null으로 인해 버그로 인해 또는 유효한 이유 가있는 경우 테이블에 삽입하는 경우 삽입이 실패하지 않기를 원합니다. 프로그램의 더 많은 부분이 삽입 된 데이터에 의존하지만이 특정 열에는 의존하지 않는다고 가정 해 봅시다. 따라서 삽입 단계 대신 현재 처리 단계에서 오류가 발생할 위험이 있습니다. 그래서 NOT NULL 제약 조건을 사용하고 싶지 않습니다.

NullPointerException에 따라 순진하게

데이터가 항상있을 것으로 예상되는 것처럼 데이터를 사용하고 (실제로 사실이어야 함) 적절한 수준에서 결과 NPE를 포착 할 수 있습니다 (예 : 현재 항목의 처리가 중지되지만 전체 처리 진행이 아님) ). 이것이 "실패"원칙이며 나는 종종 그것을 선호합니다. 그것이 버그라면 적어도 NPE를 기록합니다.

그러나 다양한 종류의 누락 된 데이터를 구별 할 수있는 능력을 잃었습니다. 예를 들어 누락 된 데이터의 경우 데이터를 남겨 둘 수 있지만 다른 데이터의 경우 처리를 중지하고 관리자에게 알려야합니다.

null각 액세스 전에 확인 및 사용자 정의 예외 발생

커스텀 예외는 예외를 기반으로 올바른 조치를 결정할 수 있도록 해줄 것 같습니다.

하지만 어딘가에서 확인하는 것을 잊어 버린 경우 어떻게해야합니까? 또한 null 검사로 코드를 혼란스럽게 만들지 않습니다.

이 방법으로 선택하면 어떤 패턴이 접근 방식에 가장 적합합니까?


내 접근 방식에 대한 생각과 의견을 환영합니다. 또한 모든 종류의 더 나은 솔루션 (패턴, 원리, 코드 또는 모델의 더 나은 아키텍처 등).

편집하다:

ORM을 사용하여 DB에서 지속성 객체로의 매핑을 수행한다는 점에서 또 다른 제약이 있습니다. 따라서 해당 수준에서 null 검사를 수행하면 작동하지 않습니다 (null이 해를 끼치 지 않는 부분에서 동일한 객체가 사용되기 때문에) . 지금까지 제공된 답변 이이 옵션을 언급했기 때문에 이것을 추가했습니다.


5
"일부 열은 null 일 수 있지만 현재 처리 컨텍스트에서 오류가 발생합니다. ... 삽입이 테이블에 null을 넣는 경우 삽입이 실패하는 것을 원하지 않습니다."이러한 두 가지 요구 사항은 다음과 같습니다. 모순. 그건 불가능 당신이 두 가지 조건 중 하나를 휴식을 취할 때까지 해결책을 찾기 위해.
Kilian Foth

@KilianFoth 글쎄, 내 이완은 "현재 처리"컨텍스트의 오류가 삽입 할 때보 다 덜 심각하다는 것입니다. 따라서 드문 처리 오류를 받아들이지 만 처리 할 수있는 견고한 디자인을 원합니다. 그렇기 때문에 좋은 해결책이 아닌 NOT NULL은 여기서 불가능합니다.
jhyot

1
너무 많은 오류를 받아들이는 경우 해당 오류의 작성자는 오류를 수정하지 않습니다. 지저분한 삽입 문이 성공하면 어떤 문제를 해결해야합니까? 실패하지 않고 나쁜 데이터를 받아들이는 것이 강력하다고 생각하십니까?
Tulains Córdova

@ user61852 오류를 명시 적으로 수락하지 않지만 오류를 정상적으로 처리하고 싶습니다. 널 포인터를 삼키는 것은 의문의 여지가 없습니다. 또한 삽입이 성공해야하지만이 특정 필드를 설정하지 않아도되는 다른 많은 부품보다 비즈니스에 의해 정의 된대로 부품이 실제로 객관적으로 중요하지 않은 경우 어떻게해야합니까? 삽입은 값을 추가하도록 강제 할 수있는 사용자 항목이 아니라 누락이 버그 일 가능성이 큰 다른 코드에서 발생합니다 (삽입을 중단하기에 충분히 중요하지는 않습니다).
jhyot

1
데이터베이스에서 열을 NOT NULL로 표시하는 것이 최선의 해결책입니다. 열이 널 입력 가능하면 코드는 스토리지 메커니즘이 허용하기 때문에 예상하지 않더라도 케이스를 처리해야합니다.
Jon Raynor

답변:


9

결과 세트에서 객체를 빌드하는 매핑 코드에 null 검사를 넣습니다. 이렇게하면 검사가 한곳에 이루어지고 오류가 발생하기 전에 코드가 레코드 처리를 반쯤 수행 할 수 없습니다. 응용 프로그램 흐름의 작동 방식에 따라 각 레코드를 한 번에 하나씩 매핑하고 처리하는 대신 모든 결과를 전처리 단계로 매핑 할 수 있습니다.

ORM을 사용하는 경우 각 레코드를 처리하기 전에 모든 null 검사를 수행해야합니다. recordIsValid(recordData)모든 null 검사 및 기타 유효성 검사 논리를 한곳에서 (다시) 유지할 수 있는 -type 방법을 권장합니다 . 나는 널 검사와 나머지 프로세싱 로직을 섞지 않을 것이다.


감사합니다. 좋은 통찰력입니다! 실제로 ORM을 사용하고 있으므로 해당 수준의 검사가 작동하지 않습니다. 그러나 지속성 개체에서 실제 도메인 개체에 대한 매핑도 있습니다. 전처리 단계에서 매핑 및 유효성 검사가 가능한지 확인하겠습니다.
jhyot

ORM을 바꾸면 어떻게 될까요? 소스에서 이것을 방어하는 것이 좋습니다 (Doc Brown의 답변 참조).
Robbie Dee

@RobbieDee : 상관 없습니다. 맵핑 코드를 다시 작성해야하는 경우 널 점검이 있고 다시 작성의 일부로 수정하거나, 비즈니스 오브젝트에서 널 점검을 수행하는 별도의 메소드가 있으므로 다시 작성할 필요가 없습니다. Doc Brown이 암시하는 것처럼 때로는 기본값을 사용하여 해당 사실을 고집하는 대신 데이터가 누락 된 것을 확인하는 것이 중요합니다.
TMN

이는 ETL 흐름에서 더 많이 발생해야합니다. 당신은 여전히 ​​이런 식으로 노력을 복제 할 위험이 있습니다.
Robbie Dee

6

null을 삽입하는 것은 오류 인 것 같지만 데이터를 잃고 싶지 않기 때문에 삽입 시이 오류를 적용하는 것이 두렵습니다. 그러나 필드가 null이 아니어야하는 경우 데이터가 손실됩니다 . 따라서 가장 좋은 해결책은 처음에 널 필드가 잘못 저장되지 않도록하는 것입니다.

이를 위해 해당 데이터에 대한 신뢰할 수있는 하나의 영구 저장소 인 데이터베이스에서 데이터가 올바른지 확인하십시오. 널 (null) 제한 조건을 추가하지 마십시오. 그러면 코드가 실패 할 수 있지만 이러한 실패는 즉시 버그를 알리므로 이미 데이터 손실을 유발하는 문제를 해결할 수 있습니다. 버그를 쉽게 식별 하고 코드 를 테스트 한 후 두 번 테스트 할 수 있습니다. 데이터 손실 및 프로세스로 이어지는 버그를 수정하고 널에 대해 걱정할 필요가 없으므로 데이터의 다운 스트림 처리를 크게 단순화 할 수 있습니다.


2
답변 해주셔서 감사합니다. 귀하의 솔루션이 올바른 방법이라는 데 동의하며, 간결하게 말하셨습니다. 영향을받지 않는 제약 조건으로 인해 어려워 지거나 불가능할 수 있습니다 (예 : 테스트에 사용할 수없는 리소스 또는 기존 코드를 자동으로 테스트 할 수 있도록하는 등).하지만 다른 방법을 시도하기 전에이 솔루션이 작동하는지 확실히 확인해야합니다. 원래 생각에서 나는 소스에서 문제를 해결할 수 없다고 너무 빨리 생각했을 것입니다.
jhyot

@jhyot 좋아. 깨끗한 방법으로 일을 할 수 없을 때 실망합니다. 내 대답은 적어도 비슷한 문제가 있지만 사실 후에 엉망을 정리하는 대신 근본 원인을 공격 할 수있는 다른 사람들에게는 적어도 유용 할 수 있기를 바랍니다.
복원 Monica Monica

5

질문 에서이 문장과 관련하여 :

이것은 "이론적으로"발생하지 않아야합니다. 따라서 데이터가 잘못되었거나 코드의 버그를 가리키는 경우

나는 항상이 인용문을 높이 평가했다 ( 이 기사 제공 ).

초보자 프로그래머가 자신의 주요 업무가 프로그램 충돌을 막고 있다고 생각하면 재미 있습니다. 이 화려한 실패 주장이 그런 프로그래머에게는 그리 매력적이지 않을 것이라고 생각합니다. 더 숙련 된 프로그래머는 올바른 코드가 훌륭하고 충돌하는 코드가 개선을 사용할 수 있지만 충돌하지 않는 잘못된 코드는 끔찍한 악몽이라는 것을 알고 있습니다.

기본적으로 : Postel의 법칙을 지지하는 것처럼 들립니다 . "보내는 것에 보수적이며, 받아들이는 것에 자유 주의적입니다." 이론적으로 훌륭하지만 실제로이 "견고성 원칙"은 적어도 장기적으로, 때로는 단기적으로는 강력 하지 않은 소프트웨어로 이어집니다 . (Eric Allman의 논문 Robustness Principle Reconsidered를 비교하십시오 .이 프로토콜은 주로 네트워크 프로토콜 사용 사례에 중점을두고 있지만 주제를 철저히 처리합니다.)

데이터베이스에 데이터를 잘못 삽입하는 프로그램이있는 경우 해당 프로그램이 손상 되어 수정 해야합니다 . 문제를 문서화하면 문제가 계속 악화 될뿐입니다. 이것은 중독자가 중독을 계속할 수있게 하는 것과 동등한 소프트웨어 엔지니어링 입니다.

그러나 실용적으로 말해서, 때로는 일시적으로, 특히 느슨하고 깨진 상태에서 엄격하고 정확한 상태로의 완벽한 전환의 일환으로 "깨진"동작을 활성화해야 할 때가 있습니다. 이 경우 잘못된 삽입이 성공할 수있는 방법을 찾고 "정식"데이터 저장소가 항상 올바른 상태가되도록 합니다. 이를 수행하는 다양한 방법이 있습니다.

  • 데이터베이스 트리거를 사용하여 잘못된 삽입을 올바른 삽입으로 변환 (예 : 누락 / 널 값을 기본값으로 대체)
  • 잘못된 프로그램이 "올바르지 않은"별도의 데이터베이스 테이블에 삽입되도록하고, 테이블에서 수정 된 데이터를 표준 데이터 저장소로 이동시키는 별도의 스케줄 된 프로세스 또는 기타 메커니즘이 있어야합니다.
  • 쿼리 측 필터링 (예 : 뷰)을 사용하여 데이터베이스에서 검색된 데이터가 정지 된 데이터가 아닌 경우에도 항상 올바른 상태인지 확인하십시오.

이러한 모든 문제를 회피하는 한 가지 방법은 쓰기 문제를 일으키는 프로그램과 실제 데이터베이스간에 제어하는 API 계층삽입하는 것 입니다.

문제의 일부는 잘못된 쓰기를 생성하는 모든 위치를 알지 못하거나 업데이트하기에 너무 많은 부분이 있다는 것입니다. 그것은 무서운 상태이지만, 처음에는 일어날 수 없었습니다.

표준 프로덕션 데이터 저장소에서 데이터를 수정할 수있는 소수 이상의 시스템을 확보하자마자 문제가 될 수 있습니다 . 해당 데이터베이스에 대해 중앙에서 어떤 것도 유지할 수있는 방법이 없습니다 . 더 적은 수의 프로세스가 쓰기를 발행하도록 허용하고 필요에 따라 삽입하기 전에 데이터를 사전 처리 할 수있는 "게이트 키퍼"로 사용하는 것이 좋습니다. 이를위한 정확한 메커니즘은 실제로 특정 아키텍처에 따라 다릅니다.


"데이터베이스에 데이터를 잘못 삽입하는 프로그램이있는 경우 해당 프로그램이 손상되어 수정해야합니다." 이론 상으로는 훌륭하지만 실제로는 여전히 기록을 추가하고 일부위원회는 "NA"또는 "없음"사용 여부에 대해 계속 토론하고 있습니다.
JeffO

@JeffO :위원회 에 데이터베이스에 "NA", "None", NULL 등 을 저장할 것인지에 대해 토론해서는 안됩니다 . 비 기술적 인 이해 관계자 데이터가 오는 것에 지분이 밖으로 데이터베이스의 방법이 아니라 내부 표현에 사용됩니다.
Daniel Pryden

@DanielPryden : 마지막 직무에는 도메인 간 기술 변경 사항을 검토 할 아키텍처 검토위원회 (DBA 소위원회와 함께)가있었습니다. 매우 기술적이지만 2 주마다 만났으며 세부 정보를 충분히 제공하지 않으면 다음 회의에서 결정을 내릴 때까지 결정을 연기합니다. 새 코드를 통해 기능을 추가하는 것으로 구성되지 않은 사소한 시스템 변경은 대개 한 달 정도 걸립니다.
TMN

@DanielPryden-텍스트 상자 레이블에 대한 고위 경영진 토론에 참석했습니다. 응용 프로그램이나 데이터베이스에서 이름을 짓는 것과는 아무런 관련이 없다고 주장 할 수는 있지만 그렇게합니다.
JeffO

이러한 종류의 변경에 대한 추가 승인을 얻는 것에 대한 의견에 대한 응답으로, "잘못된"값에 대한 나의 요점은 허용 가능한 값이 이미 어딘가에 문서화되어 있다는 것을 전제로합니다. 따라서 OP는 이러한 값을 버그로 간주해야한다고 말합니다. 데이터베이스의 스키마가 값을 허용하도록 지정된 경우 해당 값은 버그가 아닙니다. 요점은 스키마와 일치하지 않는 데이터가 있으면 데이터가 손상되었다는 것입니다. 우선 순위는 데이터와 스키마를 일치시키는 것입니다. 팀에 따라 데이터, 스키마 또는 둘 모두를 변경해야 할 수도 있습니다.
Daniel Pryden

2

" 드물지만 가능한 null 항목을 처리하기위한 좋은 아키텍처 또는 디자인 원칙이 있습니까? "

간단한 대답-예.

ETL

데이터가 데이터베이스에 들어가기에 충분한 품질인지 확인하기 위해 사전 처리를 수행하십시오. 드롭 파일의 모든 내용을 다시보고해야하며 모든 클린 데이터를 데이터베이스에로드 할 수 있습니다.

나는 poacher (dev)와 game keeper (DBA) 둘 다인 누군가로서, 제 3자가 강제로하지 않으면 데이터 문제를 해결할 수 없다는 쓴 경험을 알고 있습니다. 지속적으로 뒤로 구부리고 데이터를 통해 데이터를 마사지하는 것은 위험한 선례입니다.

마트 / 리포지토리

이 시나리오에서는 원시 데이터가 리포지토리 DB로 푸시 된 다음 위생 화 된 버전이 마트 DB로 푸시되어 애플리케이션이 액세스 할 수 있습니다.

기본값

적절한 기본값을 열에 적용 할 수 있으면 이것이 기존 데이터베이스 인 경우 약간의 작업이 필요할 수 있지만해야합니다.

일찍 실패

응용 프로그램, 보고서 세트, 인터페이스 등의 게이트웨이에서 단순히 데이터 문제를 해결하려는 유혹을 느낍니다. 나는 이것에만 의존하지 말 것을 강력히 권합니다. 다른 위젯을 DB에 연결하면 같은 문제가 다시 발생할 수 있습니다. 데이터 품질 문제를 해결하십시오.


+1이 작업을 수행하고 모든 데이터를 수집하고 응용 프로그램에서 처리 할 유효한 데이터 세트를 만듭니다.
Kwebble

1

사용 사례는 좋은 기본 값으로 안전하게 NULL을 대체 할 수 있습니다 때마다, 당신은에 변환 할 수있는 SELECT사용하여 SQL 문을 ISNULLCOALESCE. 그래서 대신

 SELECT MyColumn FROM MyTable

하나는 쓸 수있다

 SELECT ISNULL(MyColumn,DefaultValueForMyColumn) FROM MyTable

물론 ORM이 select 문을 직접 조작하거나 생성을 위해 변경 가능한 템플릿을 제공 할 수있는 경우에만 작동합니다. "실제"오류가 이런 식으로 마스킹되지 않았는지 확인해야합니다. 따라서 기본값으로 바꾸는 것이 NULL 인 경우 원하는 값인 경우에만 적용하십시오.

데이터베이스와 스키마를 변경할 수 있고 db 시스템이이를 지원하는 경우 @RobbieDee가 제안한대로 특정 열에 기본값 절을 추가하는 것을 고려할 수 있습니다. 그러나 이전에 삽입 된 NULL 값을 제거하기 위해 데이터베이스의 기존 데이터를 수정해야하며 이후에 올바른 가져 오기 데이터와 불완전한 가져 오기 데이터를 구별하는 기능도 제거합니다.

내 경험상 ISNULL을 사용하면 놀랍게 잘 작동한다는 것을 알고 있습니다. 과거에는 원래 개발자가 많은 열에 NOT NULL 제약 조건을 추가하지 않은 레거시 응용 프로그램을 유지해야했으며 나중에 이러한 제약 조건을 쉽게 추가 할 수 없었습니다. 몇 가지 이유로. 그러나 모든 경우의 99 %에서 숫자 열의 기본값은 0이고 텍스트 열의 기본값은 빈 문자열이 완전히 허용되었습니다.


이것이 작동하는 동안 각 SELECT에 대해 방어 코드를 복제해야 할 수 있습니다. NULL이 삽입 될 때 열의 기본값을 정의하는 것이 훨씬 더 좋은 방법이지만 여러 가지 이유로 가능하지 않을 수도 있습니다.
로비 디

@ RobbieDee : 그 말에 감사드립니다, 나는 그에 따라 대답을 변경했습니다. 그러나 이것이 "훨씬 낫다면"논쟁의 여지가 있습니다. CRUD 코드가 한 곳에 있으면 중복 방어 코드는 별 문제가되지 않을 수 있습니다. 그렇지 않은 경우 미리 코드 중복이 있습니다.
Doc Brown

간단한 CRUD 작업은 물론 이상적입니다. 그러나 실제로는 시스템에 복잡한 UI보기, 사용자 생성 데이터 마법사, 보고서 등이있는 경우가 많지만, 지적한 바와 같이 기본값은 처음부터 또는 최소한 초기 변환 노력이 필요합니다. 브라운 필드 개발에서 설명 한 것이 바람직 할 수 있습니다.
Robbie Dee

가장 좋은 답변입니다. 새로운 응용 프로그램은 일반적으로 통제 할 수없는 일부 새로운 데이터를 추가합니다. 잘못된 NULL은 일반적으로 레거시 데이터를 재 설계된 데이터베이스로 가져 오는 데 사용됩니다. 며칠이 아닌 몇 시간 안에 완료 될 수 있도록 제약 조건이 해제됩니다. "큰 실패"는 종종 DBA가 제약 조건을 다시 활성화하려고 할 때 발생합니다. 계획된 적이 없었기 때문에 경영진은 종종 나쁜 데이터를 수정하는 데 몇 주일이 걸렸을 때도 남아 있습니다. 모든 앱은 기본값을 삽입하고 누락 된 데이터를보고하거나 프롬프트를 표시하여 NULL을 정상적으로 처리해야합니다.
DocSalvager

1

OP는 비즈니스 규칙과 데이터베이스 기술 세부 사항을 결합한 답변을 가정합니다.

이것은 "이론적으로"발생하지 않아야합니다. 따라서 데이터가 잘못되었거나 코드의 버그를 가리키는 경우 어떤 필드가 널인지에 따라 오류의 심각도가 다릅니다. 즉, 일부 필드의 경우 처리를 중지하고 누군가에게 통지해야합니다. 다른 필드의 경우 처리를 계속하고 누군가에게 알리는 것이 허용되어야합니다.

이것은 모든 비즈니스 규칙입니다. 비즈니스 규칙은 널 당 널에 대해서는 신경 쓰지 않습니다. 모두 데이터베이스에 null, 9999, "BOO!"가있을 수 있음을 알고 있습니다. ... 그것은 또 다른 가치 일뿐입니다. 즉, RDBMS에서 널 (null)에는 흥미로운 특성이 있으며 고유 한 용도는 무례합니다.

중요한 것은 주어진 비즈니스 객체에 대해 "무효"가 의미하는 것입니다.

드물지만 가능한 null 항목을 처리하기위한 좋은 아키텍처 또는 디자인 원칙이 있습니까?

예.

  • 비즈니스 규칙을 수업에 넣습니다.
  • 음역은 비즈니스 클래스와 데이터 저장소를 분리하는 적절한 코드 계층에 있어야합니다. ORM 코드에 넣을 수 없으면 최소한 데이터베이스에 넣지 마십시오.
  • 여기서 비즈니스 규칙없이 데이터베이스를 최대한 바보로 만드십시오. 기본값을 설정하는 것과 같은 무해한 것들조차도 당신을 물 것 입니다. 거기에 있었다.
  • 데이터베이스에서 들어오고 나가는 데이터의 유효성을 검사하십시오. 물론 이것은 비즈니스 객체의 맥락에서 수행됩니다.

데이터 검색시 예외를 던지는 것은 의미가 없습니다.

문제는 " '나쁜'데이터를 저장해야합니까?"입니다. 때에 따라 다르지:

  • 잘못된 데이터가 사용될 수 있습니다. 유효하지 않은 오브젝트 또는 오브젝트 컴포지트를 저장하지 마십시오. 모든 곳에서 복잡한 데이터 / 비즈니스 관계. 사용자는 여러 상황에서 해당 비즈니스 항목을 사용하여 주어진 시간에 모든 기능을 수행 할 수 있습니다. 저장시 잘못된 데이터의 영향 (있는 경우)은 향후 사용에 크게 의존하므로 알 수 없습니다. 해당 데이터의 통합 / 단일 프로세스가 없습니다.
  • 잘못된 데이터가있는 경우 진행할 수 없습니다 - 잘못된 데이터를 저장할 수 있습니다. 그러나 프로세스의 다음 단계는 모든 것이 유효 할 때까지 계속 될 수 없습니다. 예를 들어 소득세를내는 것. 데이터베이스에서 검색 할 때 소프트웨어가 오류를 지적하고 유효성 검사없이 IRS에 제출할 수 없습니다.

0

null을 처리하는 방법은 여러 가지가 있으므로 데이터베이스 계층에서 응용 프로그램 계층으로 넘어갑니다.


데이터베이스 계층

금지 할 수 있습니다 . 비록 비현실적이지만.

열별로 기본값구성 할 수 있습니다 .

  • 이는 열이 될 것을 요구 부재 로부터 insert그렇게 명시 널 삽입 다루지
  • insert이 열을 잘못 놓친 행에서 탐지를 방지합니다.

삽입시 누락 된 값이 자동으로 계산되도록 트리거구성 할 수 있습니다 .

  • 이 계산을 수행하는 데 필요한 정보가 있어야합니다.
  • 그것은 느려질 것이다 insert

쿼리 계층

불편한 곳에 건너 뛸 수 있습니다 null.

  • 그것은 주요 논리를 단순화
  • "잘못된 행"을 감지하지 못하므로 다른 프로세스를 점검해야합니다.
  • 각 쿼리를 계측해야합니다.

쿼리에서 기본값을 제공 할 수 있습니다 .

  • 그것은 주요 논리를 단순화
  • "잘못된 행"을 감지하지 못하므로 다른 프로세스를 점검해야합니다.
  • 각 쿼리를 계측해야합니다.

참고 : 자동 생성 방법이있는 경우 각 쿼리를 계측하는 것이 반드시 문제가되지는 않습니다.


응용 계층

금지 된 테이블을 미리 확인할 수 있습니다 null.

  • 그것은 주요 논리를 단순화
  • 그것은 실패 시간을 향상시킨다
  • 사전 점검 및 애플리케이션 로직을 일관되게 유지해야합니다.

금지 된 상황이 발생 하면 처리중단 할 수 있습니다 null.

  • 어떤 열이 있고 어떤 열 null이 아닌지에 대한 지식이 중복되는 것을 피합니다.
  • 그것은 여전히 ​​비교적 간단합니다 (확인 + 리턴 / 던져)
  • 프로세스를 재개 할 수 있어야합니다 (이미 이메일을 보낸 경우 두 번 또는 백 번 보내지 마십시오!)

금지 된 상황이 발생 하면 행을 건너 뛸 수 있습니다 null.

  • 어떤 열이 있고 어떤 열 null이 아닌지에 대한 지식이 중복되는 것을 피합니다.
  • 그것은 여전히 ​​비교적 간단합니다 (확인 + 리턴 / 던져)
  • 프로세스를 재개 할 필요가 없습니다.

한 번에 하나씩 또는 배치별로 금지 된 문제가 발생 하면 알림을 보낼 수 있습니다 null.이 방법은 위에 제시된 다른 방법에 무료입니다. 그러나 가장 중요한 것은 "무엇입니까?"입니다. 특히, 행에 패치가 적용되고 재 처리가 필요한 경우 이미 처리 된 행을 필요한 행과 구분할 수있는 방법이 있는지 확인해야합니다. 재 처리 중입니다.


귀하의 상황을 감안할 때 응용 프로그램의 상황을 처리하고 다음 중 하나를 결합합니다.

  • 중단알림
  • 건너 뛰기통지

나는 처리가 시간이 걸릴 수있는 경우 어떻게 든 진전을 보장하기 위해 가능한 한 건너 뛰는 경향이 있습니다.

건너 뛴 행을 다시 처리 할 필요가없는 경우 간단히 로깅하면 충분하며 건너 뛴 행 수와 함께 프로세스가 끝날 때 전송 된 전자 메일은 적절한 알림이됩니다.

그렇지 않으면 행을 수정하고 다시 처리하기 위해 사이드 테이블을 사용합니다. 이 보조 테이블은 간단한 참조 (외래 키없이)이거나 전체 사본 일 수 null있습니다. 주 데이터를 정리하기 전에 처리 할 시간이 없으면 비용이 더 많이 들지만 후자는 더 비쌉니다 .


-1

데이터베이스 유형을 언어 유형으로 변환하거나 맵핑 할 때 널을 처리 할 수 ​​있습니다. 예를 들어 C #의 경우 모든 유형에 대해 널을 처리하는 일반 메소드가 있습니다.

public static T Convert<T>(object obj)
        {
            if (obj == DBNull.Value)
            {
                return default(T);
            }

            return (T) obj;
        }

public static T Convert<T>(object obj, T defaultValue)
        {
            if (obj == DBNull.Value)
            {
                T t = defaultValue;
                return t;
            }

            return (T) obj;
        }

또는 조치를 수행하려는 경우 ...

 public static T Convert<T>(object obj, T defaultValue)
        {
            if (obj == DBNull.Value)
            {
                //Send an Alert, we might want pass in the name
                //of column or other details as well
                SendNullAlert();
                //Set it to default so we can keep processing
                T t = defaultValue;
                return t;
            }

            return (T) obj;
        }

그런 다음이 경우 "Sample"유형의 개체에 대한 매핑에서 모든 열에 대해 null을 처리합니다.

public class SampleMapper : MapperBase<Sample>
    {
        private const string Id = "Id";
        private const string Name = "Name";
        private const string DataValue = "DataValue";
        private const string Created = "Created";

        protected override Sample Map(IDataRecord record)
        {
            return new Sample(
                Utility.Convert<Int64>(record[Id]),
                Utility.Convert<String>(record[Name]),
                Utility.Convert<Int32>(record[DataValue]),
                Utility.Convert<DateTime>(record[Created])
                );
        }
    }

마지막으로, SQL 데이터 유형을보고 언어 별 데이터 유형으로 변환하여 관련된 SQL 쿼리 또는 테이블을 기반으로 모든 맵핑 클래스를 자동으로 생성 할 수 있습니다. 이것이 많은 ORM이 자동으로하는 일입니다. 일부 데이터베이스 유형에는 직접 매핑 (Geo-spatial colunms 등)이없고 특별한 처리가 필요할 수 있습니다.


누군가가 훌륭한 Java 버전을 게시하고 싶다면 ...
Jon Raynor

자바 개발자도 예제 코드를 완벽하게 이해할 수 있다고 생각합니다. 내 상황에서는 이미 ORM을 가지고 있으므로 구현할 필요가 없습니다. 그러나 귀하의 답변은 null의 기본값 만 지정하는 반면, 실제로는 훨씬 더 중요한 경우 null을 감지하고 작업을 트리거하는 것입니다 (예 : 관리자에게 잘못된 데이터에 대해 알리기).
jhyot

아, 이것에 따라 답변을 업데이트하겠습니다.
Jon Raynor

편집 된 코드는 이제 null 값에 대해 하나의 기본 동작을 갖습니다 (즉, 완전히 제네릭 임). 그것은 원래 질문의 두 번째 옵션과 매우 유사합니다. 즉, null을 던지고 어딘가에 잡습니다. 그러나 거기에 명시된 바와 같이, 어떤 가치가 결여되어 있는지에 따라 행동을 차별화해야합니다.
jhyot
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.