데이터베이스의 관계형 모델이 중요한 이유


61

상사와 데이터베이스를 구현해야하는 프로젝트에 접근하고 있습니다. 우리는 시작이 매우 작기 때문에 업무 환경은 매우 개인적입니다.

그는 이전에 회사 데이터베이스 중 하나를 제공했으며 RDBMS를 위해 학교에서 배운 내용에 대해 완전히 반대했습니다. 예를 들어, 여기에는 하나의 테이블 (독립 데이터베이스 당)로 구성되는 전체 데이터베이스가 있습니다. 이러한 테이블 중 하나는 열이 20 개 이상이며 컨텍스트에 따라 테이블의 일부 열 이름이 있습니다 .

lngStoreID | vrStoreName | lngCompanyID | vrCompanyName | lngProductID | vrProductName

요점은 엔티티 데이터 (이름, 크기, 구매 날짜 등)를 보유하는 개별 테이블이 있어야하는 곳마다 데이터베이스마다 하나의 큰 테이블에 표시한다는 것입니다.

이 디자인을 개선하고 싶지만 제대로 정규화되고 세그먼트 화 된 데이터 모델이 실제로이 제품을 개선하는 이유를 잘 모르겠습니다. 대학의 데이터베이스 디자인에 익숙하고 이를 수행 하는 방법 을 알고 있지만 이것이 실제로 데이터베이스를 개선하는 이유 는 확실하지 않습니다 .

좋은 관계형 스키마가 데이터베이스를 개선하는 이유는 무엇입니까?


33
한마디 : 정규화.
Robert Harvey

9
유권자를 닫으십시오-자신을 정당화하십시오! :-)
Robbie Dee

6
기술적으로 건전하지 않더라도 신입 사원은 확립 된 절차를 비판하는 것이 일반적입니다. 먼저 상사가 그렇게 만든 이유를 알아 보십시오. 그 사람은 좋은 디자인이 아니라는 것을 잘 알고 있지만, 더 잘 할 수있는 지식 (또는 시간이 없음)을 알고있을 것입니다. 현재 디자인의 이유를 정중하게 인정하면 제안한 변경 사항이 더 긍정적으로 나타날 수 있습니다.
Pedro

5
He [the boss] had given me one of his databases before and it completely went against what I was taught (and read about) in school for RDBMS<-현실 세계에 오신 것을 환영합니다!
Möoz

5
내가 좋아하는 관계형 데이터베이스 인용문이 떠오른다. "아파치거나 정상화 될 때까지 비정규 화"
Jake

답변:


70

성능 주장은 일반적으로 가장 직관적입니다. 특히 정규화되지 않은 데이터베이스에 올바른 인덱스를 추가하는 것이 어려울 수있는 방법을 지적하려고합니다 (참고 : 비정규 화가 실제로 성능을 향상시킬 수있는 엣지 사례가 있지만 관계형 데이터베이스에 익숙하지 않은 경우에는 쉽지 않을 것입니다) 이 경우를 참조하십시오).

다른 하나는 스토리지 크기 인수입니다. 중복성이 많은 비정규 화 된 테이블에는 훨씬 더 많은 스토리지가 필요합니다. 이는 또한 성능 측면에서 중요합니다. 데이터가 많을수록 쿼리 속도가 느려집니다.

이해하기 조금 더 어려운 주장도 있지만 실제로 더 많은 하드웨어를 던져서 해결할 수 없기 때문에 더 중요합니다. 이것이 데이터 일관성 문제입니다. 올바르게 표준화 된 데이터베이스는 특정 ID를 가진 제품의 이름이 항상 동일하도록 자체적으로 관리합니다. 그러나 비정규 화 된 데이터베이스에서는 이러한 불일치가 가능하므로 불일치를 피할 때 특별한주의를 기울여야합니다. 불일치를 피하려면 프로그래밍 시간이 오래 걸리고 여전히 버그로 인해 고객 만족도가 높아집니다.


19
비정규 화의 주요 장점 중 하나는 데이터웨어 하우징입니다 . 특히 변경되지 않는 대량의 데이터가 있고 스토리지 공간을 희생하여 더 빠르고 효율적으로 쿼리하려는 경우입니다. 좋은 대답은 3NF 이외의 것이 왜 바람직한 지 확실하지 않은 SQL 초보자에게는 FYI 일뿐입니다.


11
일관성 주장이 왜 "어려워 지는지"잘 모르겠습니다. 값이 변경되면 해당 값의 모든 사본을 업데이트해야합니다. 단일 사본을 업데이트하면 동일한 데이터의 수백 또는 수천 개의 사본을 업데이트하는 것보다 오류가 덜 발생합니다. 이는 데이터 간의 관계 에도 동일하게 적용됩니다 . (관계를 두 가지 방식으로 저장 한 경우 관계의 두 복사본을 모두 업데이트해야합니다.) 이는 비정규 화 된 DB에서 매우 일반적인 문제입니다. 그건 아주 (예외가보기 유형 사용을 구체화한다) 실제로이 손상을 방지하기 어렵다.
jpmc26

4
마지막 단락은 굵게 강조 표시해야합니다. :-) 정규화가 없으면 데이터 무결성을 보장 할 수 없습니다. 모든 비정규 화 된 데이터베이스는 결국 어떤 종류의 데이터 이상을 나타 내기 때문에 Business Logic 계층에서만 입력을 제어하는 ​​것은 어리석은 일 입니다.
DanK

2
@IsmaelMiguel 일반적인 관행은 이와 같은 마스터 데이터는 데이터베이스에서 절대로 삭제되지 않는 것입니다. 더 이상 사용할 수 없다는 플래그를 설정하여 소프트 삭제 만 할 수 있습니다. 이 특정 경우 제품과 주문간에 외래 키 관계를 갖는 것이 좋습니다. 즉, 주문에서 참조하는 제품을 삭제하려고 할 때 데이터베이스에서 오류가 발생합니다.
Philipp

24

상사와 데이터베이스를 구현해야합니다 ...

전용 데이터베이스 관리 소프트웨어를 사용하는 것이 훨씬 쉬울 수 있습니다 (죄송하지만 저항 할 수 없음).

lngStoreID | vrStoreName | lngCompanyID | vrCompanyName | lngProductID | vrProductName

이 데이터베이스가 언제, 누구와 어디서, 어느 제품을 판매했는지 "로깅"에만 관심이있는 경우, "OK 데이터베이스"정의를 충분히 확장 할 있습니다. 이 데이터가 사용되는 경우 아무것도 다른, 그것은 정말 매우 가난합니다.

그러나 ...

이 데이터를 사용하는 응용 프로그램 / 쿼리가 제대로 수행되지 않습니까? 그렇지 않다면 해결할 실제 문제가 없습니다. 물론,보기 흉한 느낌이 들지만, 작동 하면 더 좋을 수있는 "점"을 얻지 못할 것입니다.

데이터 모델링이 잘못되어 발생하는 것처럼 보이는 명확한 증상 (예 : 문제)을 발견하면 더 나은 솔루션을 프로토 타이핑하십시오. 이 "데이터베이스"중 하나를 복사하여 데이터를 정규화하고 솔루션이 더 잘 실행되는지 확인하십시오. 그것이 훨씬 나아지면 ( 그리고이 데이터의 모든 업데이트 작업이 크게 향상 될 것으로 기대합니다 ) 상사에게 가서 개선 사항을 보여주십시오.

.. well .. Views로 데이터에 대한 "단일 테이블보기"를 완벽하게 재현 할 수 있습니다.


11
단일 테이블 weltanschauung에 대한 내성은 종종 조인을 이해하지 못하는 SQL에 익숙하지 않은 사람들, 특히 누락 된 데이터, 즉 외부 조인과 관련하여 발생합니다.
Robbie Dee

6
@RobbieDee 좀 더 일반적으로, 비정규 화 된 데이터가 일관성이 없어져 손상되는 것을 본 사람들입니다. 나는 그런 사람입니다. 필 (Phill)이 제안하는 상황에서 이런 종류의 구조만을 고려할 것이다. 이것은 데이터가 절대로 업데이트 되지 않거나 다른 소스로부터 완전히 삭제되어 완전히 업데이트되어 업데이트 되지 않는 일종의 로깅 /보고 테이블 이다.
jpmc26

2
응용 프로그램이 이와 같은 데이터베이스에서 정상적으로 수행 되더라도 제대로 정규화 된 데이터베이스처럼 유연하지 않습니다. 상점 이름 또는 회사 이름이 변경되면 상점 또는 회사 테이블 대신 모든 곳에서 업데이트해야합니다. 경우에 따라 데이터가 주로 보관 목적으로 수집되는 경우와 같이 실제로 원하는 것일 수도 있지만 특정 응용 프로그램에 대한 자세한 정보가 필요합니다.
Zach Lipton

1
@Zach : 동의합니다. 이것이 판매 로그가 잠재적으로 수용 가능한 이유입니다. 각 판매가 "매장의 현재 이름"이 아니라 판매 당시 이름을 지정한 상점과 연관되기를 원한다고 가정 한 후 "정규화"를 시도하면 상당한 복잡성이 발생합니다 (테이블 기록 저장소 이름 때문에). (storeid 당 하나의 값이 아니라 시간이 지남에 따라 시리즈 일 필요가 있음)
Steve Jessop

아마도 제안 된 정규화에 의해 도입 된 유일한 복잡성이 이제 보고서에 필요한 모든 열을 가져 오기 위해 쿼리에 조인이 필요하다는 것이라면 그 변경을 수행하지 않아도됩니다. )
Steve Jessop

14

좋은 관계형 스키마가 데이터베이스를 개선하는 이유는 무엇입니까?

답은 항상 데이터베이스를 향상시키는 것은 아닙니다 . 당신은 아마 당신이 가르친 것을 제 3 정형 이라고 부릅니다 .

다른 상황은 일부 상황에서 유효하며, 이는 귀하의 질문에 대답하는 열쇠입니다. 예제는 First Normal Form 과 같 으며 현재 상태에 대해 더 잘 느끼도록 도와줍니다.

3NF 규칙은 데이터베이스를 "개선"하는 데이터 간의 관계를 설정합니다.

  1. 유효하지 않은 데이터가 시스템에 입력되는 것을 방지하십시오 (관계가 일대일 인 경우 위에 작성된 코드에도 불구하고 오류가 발생 함). 데이터가 데이터베이스에서 일관성이있는 경우 데이터베이스 외부에서 불일치가 발생할 가능성이 줄어 듭니다.

  2. 코드를 검증하는 방법을 제공합니다 (예 : 다 대일 관계는 객체의 속성 / 동작을 제한하는 신호입니다). 데이터베이스를 사용하기 위해 코드를 작성할 때 프로그래머가 데이터 구조를 코드 작동 방식의 지표로 인식하는 경우가 있습니다. 또는 데이터베이스가 코드와 일치하지 않으면 유용한 피드백을 제공 할 수 있습니다. (불행히도 이것은 희망적인 생각과 비슷합니다.)

  3. 데이터베이스를 구축 할 때 실수를 줄 이도록 도와주는 규칙을 제공하여 데이터베이스 수명 동안 발생할 수있는 임의의 요구 사항을 기반으로 데이터베이스를 구축하지 않도록합니다. 대신 특정 목표를 달성하기 위해 정보를 체계적으로 평가하고 있습니다.

  4. 적절한 데이터베이스 구조는 데이터 쿼리를 최소화하고, 데이터를 검색하기위한 스토리지 호출을 최소화하고, 메모리 내 리소스를 최대화하거나, 특정 데이터 집합에 대한 데이터 정렬 / 조작을 최소화하는 방식으로 데이터를 연결함으로써 성능을 향상시킵니다. 그것에 대해 실행. 그러나 "적절한"구조는 데이터 양, 데이터 특성, 쿼리 유형, 시스템 리소스 등에 따라 달라집니다. 정규화하면 성능이 저하 될 수 있습니다 (예 : 모든 데이터를 1 개의 테이블로로드하는 경우 조인 속도가 느려질 수 있음) 쿼리). 트랜잭션 처리 (OLTP)와 비즈니스 인텔리전스 (데이터웨어 하우스)는 매우 다릅니다.

소규모 데이터 세트를 보유한 소규모 회사에서는 현재 방식에 문제가 없음을 발견 할 수 있습니다. 테이블이 커짐에 따라 테이블을 사용하는 시스템이 느려질 수 있으므로 나중에 "수정"하면 고통이 될 것입니다.

일반적으로 회사가 성장함에 따라 빠른 거래를 강조하고 싶을 것입니다. 그러나 회사가 더 시급하게 필요할 수있는 다른 것들 대신이 프로젝트에 지금 시간을 보내면 회사가 실제로 성장하지 않기 때문에 그러한 문제가 발생하지 않을 수 있습니다. 이것이 바로 "사전 최적화 과제"입니다. 소중한 시간을 지금 보내십시오.

행운을 빕니다!


4
언급되지 않았지만 프로그래머에게 중요한 점은 하나의 "사물"을 편집하려면 단일 항목을 찾아서 바꾸기 위해 전체 데이터베이스를 반복하지 않고 단일 행만 편집하면된다는 것입니다.
slebetman

@slebetman 정규화 여부에 관계없이 단일 테이블에서 여러 행을 업데이트하기위한 코드 측 루프가 없어야합니다. WHERE절을 사용하십시오 . 물론 이것들은 여전히 ​​잘못 될 수 있지만 기본 키를 통해 한 행만 일치하면되기 때문에 정규화 된 상황에서는 덜 가능성이 있습니다.
jpmc26

@ jpmc26 : 데이터베이스를 반복함으로써 영향을받는 모든 행을 업데이트하는 쿼리를 구성하는 것을 의미합니다. 때로는 한 곳에서 충분합니다. 그러나 변경해서는 안되는 행에 영향을 미치지 않고 영향을받는 모든 행을 가져 오기 위해 동일한 테이블에 대한 하위 선택이 필요한 부정한 구조를 보았습니다. 심지어 단일 쿼리가 작업을 수행 할 수없는 구조를 보았습니다 (행에 따라 다른 열에 변경이 필요한 엔터티가 있음)
slebetman

이 질문에 대한 많은 훌륭한 답변이 예외는 아닙니다.
Mike Chamberlain

11

하나의 큰 "신 테이블"을 사용하는 것이 여러 가지 이유가 있습니다. 구성된 예제 데이터베이스의 문제점을 설명하고 설명하겠습니다. 스포츠 이벤트를 모델링하려고한다고 가정 해 봅시다. 우리는 게임과 그 게임에서 플레이하는 팀을 모델링하고 싶다고 말할 것입니다. 여러 테이블이있는 디자인은 다음과 같이 보일 수 있습니다 (이것은 의도적으로 매우 단순하므로 더 많은 정규화를 적용 할 수있는 위치에 걸리지 않습니다).

Teams
Id | Name | HomeCity

Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location

단일 테이블 데이터베이스는 다음과 같습니다.

TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location

먼저 그 테이블에 인덱스를 만들어 봅시다. 팀의 고향 도시에 색인이 필요한 경우 Teams테이블이나 TeamsAndGames테이블에 쉽게 추가 할 수 있습니다. 인덱스를 생성 할 때마다 인덱스는 어딘가에 디스크에 저장되고 행이 테이블에 추가 될 때 업데이트되어야합니다. Teams테이블 의 경우 이것은 매우 간단합니다. 나는 새로운 팀에 데이터베이스를 색인을 업데이트합니다. 하지만 TeamsAndGames어때요? 글쎄, 동일Teams예. 팀을 추가하면 색인이 업데이트됩니다. 그러나 게임을 추가 할 때도 발생합니다! 게임의 경우 해당 필드가 널이더라도 어쨌든 색인은 해당 게임의 디스크에 여전히 업데이트되어 저장되어야합니다. 하나의 색인에 대해서는 이것이 나쁘게 들리지 않습니다. 그러나이 표에 포함 된 여러 엔터티에 대해 많은 인덱스가 필요한 경우 인덱스를 저장하는 데 많은 공간이 낭비되고 적용되지 않는 항목에 대해 업데이트하는 데 많은 프로세서 시간이 소요됩니다.

둘째, 데이터 일관성. 두 개의 별도 테이블을 사용하는 경우 테이블에서 Games테이블까지 외래 키를 사용 Teams하여 게임에서 어떤 팀이 플레이하고 있는지 정의 할 수 있습니다. 그리고 HomeTeamIdAwayTeamId열을 nullable로 만들지 않는다고 가정 하면 데이터베이스는 내가 넣은 모든 게임에 2 개의 팀이 있고 해당 팀이 내 데이터베이스에 존재하는지 확인합니다. 그러나 단일 테이블 시나리오는 어떻습니까? 이 테이블에는 여러 엔티티가 있으므로 해당 컬럼은 널 입력 가능해야합니다 (널을 널 입력 가능하지 않고 가비지 데이터를 입력 할 수는 있지만 이는 끔찍한 아이디어입니다). 해당 열이 널 입력 가능하면 데이터베이스는 더 이상 팀이있는 게임을 삽입 할 때 더 이상 보장 할 수 없습니다.

그러나 어쨌든 그냥 가기로 결정하면 어떨까요? 해당 필드가 동일한 테이블의 다른 엔티티를 다시 가리 키도록 외래 키를 설정합니다. 그러나 이제 데이터베이스는 해당 엔티티가 올바른 유형이 아니라 테이블에 존재하는지 확인합니다. GameHomeTeamId다른 게임의 ID로 쉽게 설정할 수 있으며 데이터베이스가 전혀 불평하지 않습니다. 다중 테이블 시나리오에서 시도한 경우 데이터베이스가 적합합니다.

"글쎄, 우리는 결코 코드에서 그렇게하지 않도록 할 것"이라고 말함으로써 이러한 문제를 완화하려고 시도 할 수 있습니다. 버그가없는 코드를 처음으로 작성하는 능력과 사용자가 시도 할 수있는 모든 이상한 조합을 고려할 수있는 능력에 확신이 있다면 바로 진행하십시오. 나는 개인적으로 그 두 가지 중 하나를 수행 할 수 있다고 확신하지 못하므로 데이터베이스에 추가 안전망을 제공 할 것입니다.

(디자인이 외래 키를 사용하는 대신 행 사이의 모든 관련 데이터를 복사하는 경우에는 더욱 나빠집니다. 철자법 및 기타 데이터 불일치 문제를 해결하기가 어려울 수 있습니다. "또는 의도적 인 경우 (두 사람이 분리되어 있기 때문에)?)

셋째, 거의 모든 열은 널 입력 가능해야하거나 복사 또는 가비지 데이터로 채워 져야합니다. 게임에는 TeamName또는이 필요하지 않습니다 TeamHomeCity. 따라서 모든 게임에는 일종의 자리 표시자가 필요하거나 nullable이 필요합니다. 그리고 그것이 nullable이라면, 데이터베이스는 no없이 게임을 즐겁게 할 것 TeamName입니다. 비즈니스 로직에 그런 일이 발생해서는 안된다고 말하더라도 이름이없는 팀이 필요합니다.

별도의 테이블을 원할 경우 몇 가지 다른 이유가 있습니다 (개발자 위생 유지 포함). 큰 테이블이 더 좋은 이유는 몇 가지가 있습니다 (비정규 화로 인해 성능이 향상되는 경우가 있음). 이러한 시나리오는별로 다르지 않으며 일반적으로 인덱스가 누락되거나 다른 것이 아니라 실제로 문제임을 나타내는 성능 메트릭이있을 때 가장 잘 처리됩니다.

마지막으로, 유지하기 쉬운 것을 개발하십시오. "작동"한다고해서 괜찮다는 의미는 아닙니다. 신의 계급과 같은 신의 표를 유지하려는 것은 악몽이다. 당신은 나중에 고통에 대한 자신을 설정하고 있습니다.


1
"팀 : ID | 이름 | HomeCity". 데이터 스키마가 애플리케이션에서 Super Bowl XXXIV가 LA Rams에 의해 우승했다고 잘못 주장하지 않도록하십시오. SB XXXIV 현재 LA Rams로 알려진 팀이 우승 한 모든 선수권에 대한 쿼리에 나타나야합니다. 더 좋고 나쁜 "신 테이블"이 있으며, 당신은 확실히 나쁜 것을 제시했습니다. 더 좋은 방법은 "게임 ID | 홈 팀 이름 | 홈 팀 도시 | 원정 팀 이름 | 원정 팀 도시 | 게임 시작 등 |"입니다. "New Orleans Saints @ Chicago Bears 1p Eastern"과 같은 정보를 모델링하려는 첫 번째 시도로 이어집니다.
Steve Jessop

6

오늘의 인용문 : " 이론과 실습은 동일해야합니다 ... 이론상 "

비정규 화 된 테이블

중복 데이터가 포함 된 고유 한 홀드-테이블 (all-it-all-all) 테이블에는 한 가지 장점이 있습니다. 즉, 조인을 수행 할 필요가 없기 때문에 행에 대한보고가 매우 간단하고 실행 속도가 빠릅니다. 그러나 이것은 높은 비용으로 :

  • 관계의 중복 사본을 보유합니다 (예 : IngCompanyIDvrCompanyName). 마스터 데이터를 업데이트하려면 정규화 된 스키마보다 더 많은 행을 업데이트해야합니다.
  • 그것은 모든 것을 혼합합니다. 사용자 A는 회사 정보 만 업데이트하고 사용자 B는 제품 정보 만 업데이트 할 수 있도록 데이터베이스 수준에서 쉽게 액세스 제어를 수행 할 수 없습니다.
  • 데이터베이스 수준에서 일관성 규칙을 보장 할 수 없습니다 (예 : 회사 ID에 회사 이름이 하나만 있도록 기본 키).
  • 정규화 된 테이블의 크기와 여러 인덱스의 통계를 활용하여 복잡한 쿼리에 대한 최적의 액세스 전략을 식별 할 수있는 DB 옵티마이 저의 이점을 충분히 활용하지 못합니다. 이로 인해 조인 방지의 제한적인 이점이 빠르게 상쇄 될 수 있습니다.

정규화 된 테이블

위의 단점은 정규화 된 스키마의 장점입니다. 물론 쿼리는 작성하기가 조금 더 복잡 할 수 있습니다.

즉, 정규화 된 스키마 데이터 간의 구조와 관계를 훨씬 더 잘 표현 합니다. 나는 도발적이며 그것이 주문 된 사무실 서랍 세트를 사용하는 데 필요한 규율과 쓰레기통의 사용 편의성 간의 차이점과 같은 차이점이라고 말합니다.


5

나는 당신의 질문에 적어도 두 부분이 있다고 생각합니다.

1. 다른 유형의 엔터티를 같은 테이블에 저장하면 안되는 이유는 무엇입니까?

여기서 가장 중요한 답변은 코드 가독성과 속도입니다. A SELECT name FROM companies WHERE id = ?는 a보다 훨씬 더 읽기 쉽고 SELECT companyName FROM masterTable WHERE companyId = ?실수로 넌센스를 쿼리 할 가능성이 적습니다 (예 : SELECT companyName FROM masterTable WHERE employeeId = ?회사와 직원이 다른 테이블에 저장된 경우 불가능할 수 있음). 속도와 관련하여 데이터베이스 테이블의 데이터는 전체 테이블을 순차적으로 읽거나 인덱스에서 읽음으로써 검색됩니다. 테이블 / 인덱스에 적은 데이터가 포함되어 있으면 둘 다 더 빠르며, 데이터가 다른 테이블에 저장되어있는 경우 (그리고 테이블 / 표시 중 하나만 읽어야하는 경우)에 해당됩니다.

2. 단일 유형의 엔티티가 다른 테이블에 저장된 하위 엔티티로 분리되어야하는 이유는 무엇입니까?

여기서는 데이터 불일치를 방지하기위한 것입니다. 단일 테이블 접근 방식을 사용하면 주문 관리 시스템의 경우 고객이 단일 엔티티로 주문한 제품의 고객 이름, 고객 주소 및 제품 ID를 저장할 수 있습니다. 고객이 여러 제품을 주문한 경우 데이터베이스에 고객의 이름과 주소 인스턴스가 여러 개 있습니다. 가장 좋은 경우 데이터베이스에 중복 된 데이터가있어 속도가 약간 느려질 수 있습니다. 그러나 최악의 경우는 데이터가 입력 될 때 누군가 (또는 일부 코드)가 실수를하여 회사가 데이터베이스에서 다른 주소로 끝나는 경우입니다. 이것만으로도 충분하지 않습니다. 그러나 이름을 기준으로 회사 주소를 쿼리하려는 경우 (예 :SELECT companyAddress FROM orders WHERE companyName = ? LIMIT 1) 두 주소 중 하나를 임의로 반환하면 불일치가 있음을 알지 못합니다. 그러나 쿼리를 실행할 때마다 DBMS가 쿼리를 내부적으로 해결하는 방법에 따라 실제로 다른 주소를 얻을 수 있습니다. 이로 인해 응용 프로그램이 다른 곳에서 중단 될 수 있으며 해당 중단의 근본 원인을 찾기가 매우 어려울 것입니다.

다중 테이블 접근 방식을 사용하면 회사 이름에서 회사 주소 로의 기능적 종속성 (회사가 하나의 주소 만 가질 수있는 경우)에 대해 (companyName, companyAddress) 튜플을 하나의 테이블 (예 : company) 및 다른 테이블 (예에서 (productId에, 회사 명) 튜플 order). 그러면 테이블 UNIQUE에 대한 제약 조건으로 인해 company각 회사가 데이터베이스에 단일 주소 만 갖도록하여 회사 주소에 불일치가 발생하지 않도록 할 수 있습니다.

참고 : 실제로 성능상의 이유로 각 회사마다 고유 한 companyId를 생성하고 companyName을 직접 사용하는 대신 외래 키로 사용합니다. 그러나 일반적인 접근 방식은 동일하게 유지됩니다.


3

TL; DR은 - 그들은 방법에 따라 데이터베이스를 설계하고 그들은 그들이 학교에있을 때 배웠다.

나는 10 년 전에이 질문을 쓸 수있었습니다. 이전 모델이 데이터베이스를 설계 한 방식을 이해하는 데 시간이 걸렸습니다. 다음 중 하나를 수행하는 사람과 협력하고 있습니다.

  1. Excel을 데이터베이스로 사용하거나 대부분의 데이터베이스 설계 기술을 습득했습니다.
  2. 그들은 학교에서 나왔을 때 모범 사례를 사용하고 있습니다.

실제로 테이블에 ID 번호가 있으므로 # 1이라고 의심하지 않으므로 # 2로 가정합니다.

학교를 졸업 한 후 AS / 400 (일명 IBM i) 을 사용하는 상점에서 일하고있었습니다 . 데이터베이스를 설계하는 방식에서 이상한 점을 발견하고 데이터베이스 설계 방법을 배운 방식을 따르도록 옹호하기 시작했습니다. (나는 그때 바보 였어)

왜 그런 식으로 일을했는지 ​​나에게 설명하기 위해 환자 나이 많은 프로그래머가 필요했습니다. 그들은 나보다 오래된 프로그램을 중단시킬 수 있었기 때문에 스키마를 변경하지 않았습니다. 말 그대로, 한 프로그램의 소스 코드는 내가 태어나 기 전 해의 작성 날짜를 가졌습니다. 우리가 작업하고 있던 시스템에서 그들의 프로그램 은 데이터베이스의 쿼리 플래너가 처리하는 모든 논리와 작업을 구현해야했습니다. (쿼리 중 하나에서 EXPLAIN을 실행하면 알 수 있습니다)

그는 내가 구현하려는 기술에 대해 최신 정보를 얻었지만 "내가 가르치는 것과 상반되기 때문에"변경하는 것보다 시스템을 계속 실행하는 것이 더 중요했습니다. 우리 모두의 모든 새로운 프로젝트는 우리가 할 수있는 관계형 모델을 최대한 활용하기 시작했습니다. 불행히도 당시의 다른 프로그래머 / 컨설턴트는 여전히 해당 시스템의 이전 제약 조건으로 작업하는 것처럼 데이터베이스를 설계했습니다.


내가 만난 것에 대한 몇 가지 예는 관계형 모델에 맞지 않습니다.

  • 날짜는 Julian 날짜 번호 로 저장되었으며 실제 날짜를 얻으려면 날짜 테이블에 조인해야했습니다.
  • 동일한 유형의 연속 열 비정규 테이블 (예를 들어 code1,code2, ..., code20)
  • 길이 M의 N 문자열 배열을 나타내는 NxM 길이 CHAR 열

제가 이러한 디자인 결정을 한 이유는 데이터베이스를 처음 디자인 할 때 시스템의 제약 조건을 바탕으로 한 것입니다.

날짜 -날짜 정보 (월 또는 일 또는 주중)를 사용하여 날짜를 처리하는 데 모든 정보가 포함 된 가능한 모든 날짜의 테이블을 만드는 것보다 처리 시간이 더 걸린다고 들었습니다.

동일한 유형의 순차 열 -프로그램 환경에서 프로그램이 행의 일부에 대해 배열 변수를 작성할 수 있습니다. 그리고 읽기 작업 수를 줄이는 더 쉬운 방법이었습니다.

NxM 길이 CHAR 열 -파일 읽기 조작을 줄이기 위해 구성 값을 하나의 열에 더 쉽게 넣을 수있었습니다.

C의 프로그래밍 환경이 잘못 반영된 예는 다음과 같습니다.

#define COURSE_LENGTH 4
#define NUM_COURSES 4
#define PERIOD_LENGTH 2

struct mytable {
    int id;
    char periodNames[NUM_COURSES * PERIOD_LENGTH];  // NxM CHAR Column
    char course1[COURSE_LENGTH];
    char course2[COURSE_LENGTH];
    char course3[COURSE_LENGTH];
    char course4[COURSE_LENGTH];
};

...

// Example row
struct mytable row = {.id= 1, .periodNames="HRP1P2P8", .course1="MATH", .course2="ENGL", .course3 = "SCI ", .course4 = "READ"};

char *courses; // Pointer used to access the sequential columns
courses = (char *)&row.course1;


for(int i = 0; i < NUM_COURSES; i++) {

    printf("%d: %.*s -> %.*s\n",i+1, PERIOD_LENGTH, &row.periodNames[PERIOD_LENGTH * i], COURSE_LENGTH,&courses[COURSE_LENGTH*i]);
}

출력

1 : HR-> 수학
2 : P1-> ENGL
3 : P2- > SCI
4 : P8-> 읽기

내가 들었던 것에 따르면,이 중 일부는 당시 모범 사례로 간주되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.