리프 엔터티 속성의 중첩 된 엔터티 및 계산-SQL 또는 NoSQL 방식


10

Menu / Recipe Management라는 취미 프로젝트를 진행하고 있습니다.

이것이 나의 실체와 그들의 관계의 모습입니다.

A Nutrient는 속성 Code을 가지고Value

Ingredient컬렉션이 있습니다Nutrients

A Recipe의 컬렉션이 Ingredients있고 때로는 다른 컬렉션을 가질 수 있음recipes

A Meal의 컬렉션이 Recipes있고Ingredients

A Menu의 컬렉션이 있습니다Meals

관계는 다음과 같이 묘사 될 수있다

메뉴 엔티티 및 관계

페이지 중 하나에서 선택한 메뉴에 대해 구성 요소 (식사, 레시피, 재료 및 해당 영양소)를 기반으로 계산 된 효과적인 영양소 정보를 표시해야합니다.

현재 SQL Server를 사용하여 데이터를 저장하고 있으며 메뉴의 각 식사부터 시작하여 영양소 값을 집계하는 C # 코드에서 체인을 탐색합니다.

페이지를 요청하고 구성 요소가 때때로 변경 될 때 마다이 계산이 수행되므로 효율적인 방법이 아니라고 생각합니다.

MenuNutrients ( {MenuId, NutrientId, Value}) 라는 테이블을 유지 관리하는 백그라운드 서비스가 있고 구성 요소 (식사, 레시피, 재료)가 변경 될 때 효과적인 영양소 로이 테이블을 채우거나 업데이트합니다.

GraphDB 가이 요구 사항에 적합하다고 생각하지만 NoSQL에 대한 노출은 제한적입니다.

주어진 메뉴의 영양소를 표시하는이 요구 사항에 대한 대안 솔루션 / 접근법이 무엇인지 알고 싶습니다.

시나리오에 대한 나의 설명이 명확하기를 바랍니다.


우리는 얼마나 많은 물건을 말하고 있습니까? 성능이 실제로 문제가됩니까?
flup

@flup 평균적으로 메뉴는 8 개의 식사를 할 수 있고, 각 식사는 2 개의 레시피와 2 개의 재료를 가질 수 있으며, 각 레시피는 6-8 개의 재료를 가질 수 있습니다.
Chandu

당신의 화살이 잘못된 방향이 아닙니까?
Branko Dimitrijevic

얼간이 디너 엔티티 프레임 워크 샘플을 보셨습니까?
Akash Kava

답변:


8

요구 사항 및 아키텍처에 따라 성능 개선 옵션이있을 수 있습니다.

  • RDBMS (Sql server) 수준에서 읽기 성능향상시키기 위해 인덱싱 된 뷰를 사용할 수 있습니다 . 기본적으로 수행해야 할 작업은 다음과 같습니다 . 일반보기를 만듭니다. 해당보기에서 클러스터형 인덱스를 만듭니다 .



  • 응용 프로그램 수준에서 현금 지급 메커니즘을 사용하면 성능이 향상됩니다.
    현금을 사용할 수 있고 가능하다면 싱글 톤 게으른 현금 과 같은 현금 전략 이 도움이 될 것입니다.

NoSQL의 :
이 같은 NoSQL에 대는 SQL에 대한 좋은 기사 많이있다

: 나 부품의 이해 관계

되는 NoSQL을 사용하려면 :

DB가 3NF 이고 조인을 수행하지 않는 경우 (대량의 테이블을 선택하고 모든 객체를 모으는 것만으로도 대부분의 사람들이 웹 앱에서하는 일을 일으킨다.

사용 준비가되면 :

  • RDBMS가 자동으로 수행하는 다른 테이블 / 컬렉션의 데이터 조인과 같은 작업을 수행하기 위해 작업을 작성하게됩니다.
  • NoSQL의 쿼리 기능이 크게 손상되었습니다. MongoDb는 SQL에 가장 가까운 것이지만 여전히 매우 뒤떨어져 있습니다. 날 믿어. SQL 쿼리는 매우 직관적이고 유연하며 강력합니다. NoSql 쿼리는 없습니다.
  • MongoDb 쿼리는 하나의 컬렉션에서만 데이터를 검색하고 하나의 인덱스 만 활용할 수 있습니다. 그리고 MongoDb는 아마도 가장 유연한 NoSQL 데이터베이스 중 하나 일 것입니다. 많은 시나리오에서 이는 관련 레코드를 찾기 위해 서버로 더 많은 왕복을 의미합니다. 그런 다음 데이터 비정규 화를 시작합니다. 즉 백그라운드 작업을 의미합니다.
  • 데이터베이스가 관계형 데이터베이스가 아니라는 사실은 데이터의 일관성을 보장하기 위해 외래 키 제약 조건이없는 것을 의미합니다. 이것이 결국 데이터베이스에 데이터 불일치를 생성 할 것이라고 확신합니다. 준비하십시오. 대부분의 경우 데이터베이스의 일관성을 유지하기 위해 프로세스 작성 또는 검사를 시작하게되므로 RDBMS가이를 수행하도록하는 것보다 성능이 떨어질 수 있습니다.
  • 최대 절전 모드와 같은 성숙한 프레임 워크는 잊어 버리십시오.

NOSql 사용 여부를 결정하는 것 외에도 NOSQL DBMS 비교 에 대한 유용한 기사 와 그 의도는 일부가 높은 읽기, 낮은 쓰기, 맵 감소, HA ...
에 중점을두고 있기 때문에 여기에서 찾을 수 있습니다 ... 상기 순위 및 그들의 인기 카테고리 별, 유용 할 수있다.


자세한 내용에 감사드립니다. 링크를 확인하고 다시 연락 드리겠습니다.
Chandu

3

사실 그래프 db를 사용할 필요가 없으며 필요한 값을 하나의 상위 레벨에 저장하면됩니다. 마치 Orderand를 저장하는 것과 같습니다 OrderItems. 주문이 표시 될 때마다 총계를 계산할 필요는 없습니다. 대신 합계, 부가 가치세 및 기타 물건을 계산하고와 함께 저장하십시오 Order.

order.Subtotal = order.Items.Sum(item => item.Price);
order.Tax = order.Subtotal * 0.25m; // just a value
order.Total = order.Subtotal + order.Tax;

// fast forward time
var subTotal = order.Items.Sum(item => item.Price);
var tax = subTotal * 0.25m;
var total = subTotal + tax;

if (toal == order.Total) {
   Console.Log("Why the hell I've just re-calculated total?");
}

3

Command Query Responsibility Segregation 패턴 을 살펴 보는 것이 좋습니다 .

기본적으로 읽고 쓰는 단일 모델을 작성하는 대신 2 개의 다른 모델을 작성할 수 있습니다. 하나는 업데이트에 최적화되고 다른 하나는 쿼리 (읽기,보고 등)에 최적화됩니다. 두 가지 모델은 도메인 이벤트를 사용하여 동기화됩니다 (일반적으로 최종 일관성과 함께) (DDD 참조).

몇 달 전에이 패턴을 연구하기 시작했고 소프트웨어 모델링 방식이 바뀌 었습니다. 특히 DDD 및 이벤트 소싱과 같은 다른 기술과 함께 사용하면 크게 변화하기 때문에 쉽지 않습니다. 그러나 그만한 가치가 있습니다.

인터넷에는 많은 리소스가 있으며 CQRS 및 DDD (및 결국 이벤트 소싱)를 검색하십시오.

이 패턴은 SQL 및 noSql 모두에 사용할 수 있습니다.

귀하의 경우 영양소가 변경 될 때마다 이벤트를 시작하여 읽기에 최적화 된 읽기 모델을 업데이트 할 수 있습니다. 읽기 모델은 예를 들어 메뉴 영양소의 비정규 화 된 뷰일 수 있습니다 (효율적인 읽기를 위해 nosql db를 사용하지 않는 이유). 수행해야하는 쿼리를 기반으로 여러 읽기 모델을 가질 수 있습니다.

이 접근 방식을 사용하면 몇 가지 의미가 있지만 확장 성과 확장 성이 매우 뛰어납니다.


이것은 내가 생각한 접근법이지만 읽기 모델의 데이터를 얻는 방법에 대해서는 확실하지 않았습니다 (기본적으로 일부 프로세스는 읽기 모델의 데이터를 가져와야합니다).
Chandu

일반적으로 읽기 모델은 변경 될 때마다 업데이트됩니다. crud 작업을 사용하는 대신 명령 (작업 기반)으로 ui를 구현해야합니다. 이러한 방식으로 모든 단일 명령이 읽기 모델에 반영됩니다. 다른 쿼리를 실행할 필요가 없습니다. 설계 명령을 통해 시스템은 사용자의 실제 의도를 파악할 수 있습니다.

2

메뉴와 영양분을 처음에 얻는 방법에 크게 의존합니다. 왜 효율적이지 않을 것이라고 생각하십니까?

내가 이해 한 것에서, 당신은 DB로 가서 메뉴를 얻은 다음 다시 가서 각 레시피를 얻은 다음 다시 가서 각 재료를 얻는 등. 지연의 주요 원인 인 서버에 대한 많은 쿼리와 왕복이 있기 때문에 이것은 실제로 비효율적입니다. 이것을 SELECT N + 1 문제라고합니다.

당신이해야 할 일은 JOIN메뉴에서 영양분까지 모든 테이블에 대해 s를 사용하여 단일 쿼리에서 모든 데이터를 가져 오는 것이므로 DB 서버는 모든 관계와 인덱스를 사용하여 모든 데이터를 한 번에 얻을 수 있습니다. 클라이언트 C # 앱은 최종 결과 만 처리하고 표시합니다. 그렇게하는 것이 하나씩하는 것보다 훨씬 효율적입니다.

일반적으로 적절한 쿼리 기술과 중요한 쿼리에 대한 올바른 인덱스를 사용하면 관계형 데이터베이스는로드되는 큰 테이블에서 매우 잘 수행 될 수 있습니다.


감사합니다. 조인에 따라 다릅니다. 메뉴의 구성 요소가 때때로 변경되기 때문에 일부 페이지를 방문 할 때마다 계산을 실행하고 싶지 않습니다. 대신 백그라운드 서비스에서 계산을 수행하고 필요할 때 간단히 테이블에서 읽을 수 있습니다. 계산 문제는 구성 요소 중 하나가 변경 될 때 전체 체인을 식별하는 것입니다.
Chandu

JOIN서버에 부담이되지 않는 5 또는 6 초가 있더라도 (수백 또는 수천 개의 행을 가져 오는 것에 대해 이야기하지 않는 한) 적절한 인덱싱이 아니라면 몇 가지 관계 만 검색해도 계산이 전혀 발생하지 않습니다. 제자리에 있습니다. 빅 데이터 세트를 사용하더라도 성능에 문제가있는 경우 항상 전체 결과에 대한 뷰를 작성하고 뷰를 색인하여 결과를 미리 계산할 수 있습니다.

2

데이터를 쉽게 업데이트하고 쿼리 할 수 ​​있도록 데이터를 모델링하는 최선의 방법에 대해 생각한 것처럼 보입니다. 그러나 이제는 데이터에 대한 액세스를 제공해야합니다. 이 두 가지는 별도의 관심사입니다.

페이지를 다시로드하면 데이터베이스에 새로운 쿼리가 발생한다고 언급합니다. 또한 데이터베이스가 때때로 업데이트되고 해당 업데이트가 페이지에 적시에 표시되기를 원한다고 언급했습니다. 쿼리 오버 헤드를 줄이는 가장 좋은 방법은 쿼리를 수행하지 않는 것입니다. 동일한 쿼리를 반복해서 실행하고 동일한 결과를 얻는다면 잠시 동안 캐시하지 않는 이유는 무엇입니까? 나머지 프로젝트를 수정하지 않고 일부 캐싱 업스트림을 구현할 수 있어야합니다. 나는 휴식 에 대해 읽는 것이 좋습니다. rdbms에서 프로젝트를 구현하든이 유형의 성능에 대한 nosql 문제는 데이터베이스로 이동해야하는 횟수를 줄여서 처리하는 것이 가장 좋습니다. 60 초 안에 같은 레시피에 대해 100 개의 요청이 있다고 가정하십시오. 60 초 동안 캐시하면 데이터베이스에 한 번만 도달하므로 성능이 100 배 향상됩니다. nosql로 전환하여 동일한 수준의 개선을 위해서는 더 많은 작업이 필요합니다.

Nosql 유형 시스템은 대량의 데이터 또는 극한의 읽기 또는 쓰기 속도 요구 사항이있는 경우 훌륭한 솔루션이 될 수 있습니다. 그러나 그 추가 성능은 참조 무결성과 같은 것들을 버리는 비용이 듭니다.


1

실험이나 지식 목적으로 Graph-DB를 사용하려고하는 것처럼 보이지만 예제는 분명히 노드를 통해 드릴 다운 / 업 할 수있는 계층 적 데이터의 예입니다. Graph / Neo DB에 대한 전문가는 아니지만 사용자 /이 스키마에서 데이터를 요청할 수있는 방법에는 그다지 복잡하지 않다는 것을 알 수 있습니다. 데이터베이스 / 스키마 디자인의 선택은 어떤 유형의 데이터를 쿼리할지에 따라 달라집니다. SQLSERVER를 사용할 때 "HierarchyI"D는이 노드를 Tree의 일부로 배치하는 관점에서 가장 좋은 옵션입니다.


1

내 제안은 인간이 아닌 기계처럼 생각하는 것입니다. 반복되는 것처럼 보일지 모르지만 어떤 기계가 능숙한 지. 스스로에게 물어봐야 할 한 가지는 "어쨌든 내 페이지에 표시하려면 모든 개체를 검색해야합니까?"입니다. 그렇다면 데이터 검색과 비교하여 수행중인 작업을 계속하면 간단한 수학을 수행 할 때 CPU 사이클을 무시할 수 있습니다.

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