2009-04-29 5 views
1

나는 성공적으로 응용 프로그램을 운영하기 위해 서로 의존하는 많은 데이터베이스 관계를 가진 응용 프로그램을 가지고 있습니다. 응용 프로그램의 경첩은 일정이라고하는 모델이지만 일정에 따라 블록, 직원, 작업 제목 및 과제 (모든 블록이 함께 데이터베이스에서 과제를 가져 오게됩니다)를 가져옵니다. 하루 종일 직원 스케줄을 작성하십시오.모델 관계가 필요할 때 어떻게 오류를 방지 할 수 있습니까?

응용 프로그램을 만들 때 모든 항목이 데이터베이스에 저장되기 전에 모든 조각이 있어야한다는 확인에 많은 중점을 두었습니다. 이것은 지금까지 환상적으로 발전해 왔으며, 앱은 거의 6 개월 동안 생동감 있고 놀랐다. 딸꾹질이나 실수없이 한 달에 약 15 만 건의 요청을 제공했다. 지난 주까지.

지난 주 누군가가 일정을 변경하는 동안 데이터베이스 오류가 발생했으며 일정이 누락 된 데이터베이스에 저장되었습니다. 연결은 모든 뷰에서 호출되기 때문에이 일정이 데이터베이스에서 호출 될 때마다 응용 프로그램에서 nil을 호출 할 때 NoMethod 오류가 발생합니다.

내가 언급 한 방식으로 응용 프로그램을 설계 할 때 데이터베이스/유효성 검사에서 발생할 수있는 오류를 방지합니까? 그렇다면 어떻게 프로그래밍 방식으로 방어 할 수 있습니까? 보기에 보내기 전에 모든 관계를 점검하여 그것이 0이 아닌지 확인하십시오.

나는이 질문이 일반성이 풍부하다는 것을 알고 있으며, 내가 의미하는 바를 구체적으로 표현할 수 있다면, 의견에 알려 주시기 바랍니다.

답변

5

database-enforced foreign key constraintswrapping important groups of operations into transactions을 추가하는 것이 좋습니다.

Schedule과 Assigning 사이에 외래 키가있는 경우 데이터베이스 강제 외래 키 제약 조건으로 잘못된 삽입을 방지 할 수 있습니다. 또한 트랜잭션에서 특정 작업을 래핑하는 경우 삽입/업데이트/삭제 스트림 전체가 발생하거나 실패하여 깨끗한 상태로 되돌아 갈 수 있습니다.

+0

IIRC, 대부분의 DB에서 FK 제약 조건은 nullable 인 열에 적용 할 수 있습니다.이 경우 OP에서 문제를 보호하지 못합니다. 아마도 Ruby/Rails/특정 DB에 대해 뭔가 특별한 점이 있습니다 ... 내 대답은 FK 제약이 이미 존재한다고 가정했습니다. – rmeador

+0

데이터베이스 강제 FK 제약 조건을 사용하지 않고, Rails 검증을 통해서만 자식 개체가 만들어지고 존재하는지 확인합니다. 정보 주셔서 감사합니다! 나는 FK 제약을 조사 할 것이다! 트랜잭션 내 여러 데이터베이스 작업을 이미 래핑했지만 내 데이터베이스는 실제로이 이점을 받기 위해 트랜잭션을 지원해야합니다. 그렇지 않습니다. – BushyMark

+0

이것은 DBMS가 제약 조건을 적용해야하는 이유입니다. 제약이없는 무수한 응용 프로그램 중 하나에 버그가있는 경우 버그가 있습니다. 일정에 할당 테이블을 참조하는 외래 키 열이 있는지 여부는 완전히 명확하지 않습니다. 그렇다고해도 삽입이 실패하고 문제가 발생할 수 없습니다. 이는 DBMS가 하나이고 데이터를 공유하는 응용 프로그램이 많아서 DBMS에서 유효성 검사를 수행해야하기 때문에 응용 프로그램이 모두 DBMS를 사용하므로 최대한의 일관성을 유지하기 때문입니다. –

-1

앱이 작동하기 위해서는 사실이어야하는 것이 있다면, 그것은 바로 assert()입니다. 나는 Ruby를 간신히 사용했지만, 그 개념을 가지고 있어야한다고 생각합니다. 이를 사용하여 코드 전체의 여러 위치에서 전제 조건을 시행하십시오. 외부 (사용자) 입력을 위생 처리하고 유효성을 검사하는 것과 결합하면 사용자를 보호하기에 충분합니다. 그 정도의 검사가 끝난 후 문제가 발생하면 앱이 정당하게 추락 할 수 있다고 생각합니다 (물론 제어 된 방식으로).

당신이 겪고있는 문제가 데이터베이스에있는 버그인지 의심 스럽습니다. 당신이 간과 한 유효성 검사에 약간의 엣지 케이스가있을 가능성이 더 큽니다.

5

유효성 검사 외에 다른 대답에서 언급 한 일부 데이터베이스 제약 조건을 추가하는 경우 고아를 찾기 위해 정기적으로 데이터베이스를 스윕하는 백그라운드 작업을 실행할 수도 있습니다.

발견되면 (가능한 경우) 정리하거나 삭제하거나 비활성 상태로 표시하고 나중에 볼 수 있도록 이메일을 보냅니다. 데이터의 양과 특성에 따라 분당 1 회, 1 시간에 1 회, 하루에 한 번 ...

그런 식으로, 당신이 보유하고있는 안전 장치에도 불구하고 나쁜 데이터가 들어올 경우, 나중에보다는 오히려 빠릅니다.

+0

여기에 스택 오버플로가 있습니다. 쿼리 성능을 위해 많은 데이터를 비정규 화 (denormalize) 할 때 데이터의 유효성을 보장하는 몇 가지 백그라운드 작업이 있습니다. –

+0

이것은 환상적인 아이디어이기도합니다. 이미 backgroundrb를 사용하여 데이터베이스를 스윕하여 데이터를 제거하고 있습니다. . . 내가 고아가 된 객체를 갖지 않도록 다른 작업자를 추가하면이 작업에 대한 훌륭한 체크가 될 것입니다! 감사! – BushyMark

+0

일관성 검사 루틴을 갖는 것이 좋습니다. 그러나 파편을 청소하는 것 이상으로 문제를 해결해야합니다. 같은 나쁜 데이터를 계속 보게되면, 아직 제어 할 수 없습니다. – dkretz

1

나는 이것에 대한 비 전통적인 통념을 주장 할 것이다. 설명하는 제약 조건은 데이터베이스에 속하지 않으며 OO 코드에 속합니다."데이터베이스가 잘못되었다"는 것은 사실이 아니며, 응용 프로그램이 부적절하게 검증 된 데이터를 삽입 한 것이 확실합니다.

데이터베이스가 이러한 확인 작업을 수행하기 시작할 때 비즈니스 규칙을 스키마에 넣어야합니다. 최소한 이것은 단위 테스트를 작성하는 것이 훨씬 어렵습니다. (이것은 처음에 잡았을 가능성이 있지만, 이제 다른 테스트를 추가 할 수있는 기회입니다.)

이상적으로, RDBMS를 다른 일반 데이터 저장소로 대체하고 적절한 기능적 로직을 적절한 다른 장소에서 적절하게 활성 및 변경되지 않은 상태로 유지합니다. UI는 데이터베이스 예외를 직접 다루는 것이 훨씬 덜 DAL과 이야기해서는 안됩니다.

원하는 경우 추가 데이터베이스 제약 조건을 추가 할 수 있지만이를 엄격하게 백업으로 사용해야합니다. 보시다시피, 데이터베이스 구조 오류를 정상적으로 처리 (특히 UI가 관련된 경우)하는 것이 훨씬 어렵습니다.

+1

일반적으로 나는 당신과 동의하지만, validates_uniqueness_of와 같은 것들에 문제가된다. 여러 개의 동시 프로세스로 인해 유일성을 보장 할 수 없습니다. –

+0

동시 프로세스 자체는 문제가 아니지만 여러 개의 Ruby 프로세스 (ActiveRecords를 사용하지 않기 때문에 말할 수는 없습니다.)하지만 설명하는 예약 응용 프로그램을 거의 구현했지만 설계해야했습니다 동시 사용자를 허용하고 영웅적 데이터베이스 프로그래밍을 필요로하지 않았습니다.나는 데이터베이스가 필연적으로 그것을 다루어야한다는 피할 수 없다는 것을 암시하는 인기있는 대답을 보길 싫어한다. 적절한 추상화 레이어에서 처리 될 수 없기 때문이다. 불행히도, 그것은 전통적인 통념입니다. – dkretz

+0

Rails는 단일 스레드이므로 기존 Rails 설치에는 수백 개의 별도 Ruby 프로세스가 데이터베이스에 충돌 할 수 있습니다. 따라서 validates_uniqueness_of가 고유성을 검사 할 때와 레코드가 저장 될 때 사이에 동일한 레코드가 다른 프로세스에 의해 저장 될 수 있습니다. 지금 당장 레일스에서 ​​유일성을 보장하기를 원한다면 (그리고 별개의 게시물이 될 수도 있습니다!), 데이터베이스 제약이 유일한 선택입니다. –

관련 문제