Programing

JOIN이없는 삶… 이해와 일반적인 관행

crosscheck 2020. 12. 9. 07:51
반응형

JOIN이없는 삶… 이해와 일반적인 관행


많은 "BAW"(큰 웹 사이트)는 인덱스가있는 거대한 테이블에 의존하는 데이터 저장 및 검색 기술을 사용하고 쿼리에서 JOIN을 사용하지 않거나 사용할 수없는 쿼리 (BigTable, HQL 등)를 사용하고 있습니다. 확장 성 및 분할 데이터베이스를 처리합니다. 관련성 높은 데이터가 많을 때 어떻게 작동 합니까?

이 결합의 많은 부분이 응용 프로그램 측면에서 수행되어야한다고 추측 할 수 있지만 비용이 많이 들지 않습니까? 컴파일 할 정보를 얻기 위해 여러 테이블에 대해 여러 쿼리를 수행해야하는 경우 어떻게해야합니까? 처음부터 조인을 사용하는 것보다 비용이 많이 들기 시작하는 경우가 많지 않습니까? 당신이 가지고있는 데이터의 양에 달려 있다고 생각합니다.

그리고 일반적으로 사용 가능한 ORM의 경우 조인을 사용할 수없는 상황을 어떻게 처리 하는가? 오늘날 많이 사용되는 ORM에서이를 지원합니까? 아니면이 수준의 데이터에 접근해야하는 대부분의 프로젝트가 어쨌든 자체적으로 롤링되는 경향이 있습니까?

그래서 이것은 제가 현재하고있는 어떤 프로젝트에도 적용 할 수 없습니다. 그러나 그것은 "모범 사례"가 무엇인지에 대해서만 추측 할 수있는 몇 달 동안 제 머릿속에있는 것입니다. 필요한 규모에 도달 한 적이 없기 때문에 내 프로젝트에서이 문제를 해결할 필요가 없었습니다. 이 질문이 다른 사람들에게도 도움이되기를 바랍니다.

누군가가 아래에서 말했듯이 ORM은 조인 없이는 "작동하지 않습니다". 이 수준에서 데이터로 작업하는 개발자가 이미 사용할 수있는 다른 데이터 액세스 계층이 있습니까?

편집 : 일부 설명을 위해 Vinko Vrsalovic 은 다음과 같이 말했습니다.

"나는 snicker가 트랜잭션 데이터가 비정규 화되고 Hadoop, BigTable 또는 Cassandra 체계에서 사용되는 NO-SQL에 대해 이야기하고 싶어한다고 생각합니다."

이것이 제가 말하는 것입니다.

xkcd 참조를 잡는 사람들을위한 보너스 포인트.


제가보기에 관계형 데이터베이스는 베팅을 헤지하기위한 범용 도구입니다. 최신 컴퓨터는 충분히 빠르며 RDBMS는 단일 상자에서 상당한 크기로 성장할 수있을만큼 충분히 최적화되어 있습니다. RDBMS를 선택하면 데이터에 매우 유연하게 액세스 할 수 있고 데이터에 대해 훨씬 쉽게 코딩 할 수있는 강력한 정확성 제약 조건을 가질 수 있습니다. 그러나 RDBMS는 특정 문제에 대한 좋은 최적화를 나타내지는 않을 것이며 문제를 쉽게 변경할 수있는 유연성을 제공 할뿐입니다.

빠르게 성장하기 시작하고 단일 DB 서버의 크기 이상으로 확장해야한다는 사실을 깨달으면 갑자기 선택하기가 훨씬 더 어려워집니다. 병목 현상을 식별하고 제거해야합니다. RDBMS는 코드 펜던시의 엉뚱한 매듭이 될 것입니다. 데이터가 상호 연결 될수록 더 많은 작업을 수행해야하지만 전체를 완전히 분리 할 필요는 없습니다. 읽기가 많은 경우 간단한 복제로 얻을 수 있습니다. 시장을 포화시키고 성장이 평준화되면 부분적으로 비정규 화하고 고정 된 수의 DB 서버로 분할 할 수 있습니다. 확장 가능한 데이터 저장소로 이동할 수있는 문제 테이블이 몇 개있을 수 있습니다.

BigTable과 같은 확장 가능한 키-값 저장소가 들어오는 곳은 위의 어느 것도 작동하지 않고 단일 유형의 데이터가 너무 많아서 비정규 화 된 경우에도 단일 테이블이 하나의 서버에 비해 너무 많은 경우입니다. 이 시점에서 임의로 파티션을 나눌 수 있어야하고 여전히 액세스 할 수있는 깨끗한 API가 있어야합니다. 당연히 데이터가 너무 많은 시스템에 분산되어 있으면 이러한 시스템이 서로 많이 통신해야하는 알고리즘을 가질 수 없습니다. 많은 표준 관계형 알고리즘이 필요합니다. 당신이 제안한 바와 같이, 이러한 분산 쿼리 알고리즘은 적절하게 색인 된 관계형 데이터베이스에서 동등한 JOIN보다 더 많은 총 처리 능력을 요구할 가능성이 있습니다.

이제 대규모 데이터 세트를 수평으로 확장 할 수 있으면 (더 많은 서버를 연결하기 만하면) 확장 성의 어려운 부분이 완료됩니다. 이 규모의 지속적인 운영 및 개발은 단일 서버 앱보다 훨씬 어렵 기 때문에 완료 라고 말해서는 안되지만 , 핵심은 애플리케이션 서버가 일반적으로 얻을 수있는 한 비공유 아키텍처를 통해 확장하는 것이 사소하다는 것입니다. 필요한 데이터를 적시에 제공합니다.

일반적으로 사용되는 ORM이 JOIN을 사용할 수없는 상황을 처리하는 방법에 대한 질문에 대답하기 위해 짧은 대답은 그렇지 않다는 것 입니다. ORM은 Object Relational Mapping의 약자이며 ORM의 대부분의 작업은 단순한 객체 지향 데이터 구조의 술어 논리의 강력한 관계형 패러다임을 변환하는 것입니다. 그들이 제공하는 대부분의 가치는 단순히 키-값 저장소에서 가능하지 않을 것입니다. 실제로는 이러한 규모의 데이터 프로필이 크게 달라질 수 있고 범용 도구가 등장하기에는 너무 많은 절충점이 있다고 생각하기 때문에 특정 요구에 적합한 고유 한 데이터 액세스 계층을 구축하고 유지해야 할 것입니다. RDBMS가 가진 방식으로 지배적이됩니다. 요컨대,이 규모에서 항상 더 많은 다리 작업을해야합니다.

즉, 키-값 저장소 기본 요소 위에 어떤 종류의 관계형 또는 기타 집계 기능을 구축 할 수 있는지 보는 것은 확실히 흥미로울 것입니다. 여기에 구체적으로 언급 할 충분한 경험이 없지만, 수년 전으로 거슬러 올라가는 엔터프라이즈 컴퓨팅에 대한 많은 지식 (예 : Oracle), 학계에서 미개발 된 많은 이론적 지식, 많은 실제 지식이 있습니다. Google, Amazon, Facebook 등이지만 더 넓은 개발 커뮤니티로 걸러진 지식은 여전히 ​​상당히 제한적입니다.

그러나 이제는 많은 애플리케이션이 웹으로 이동하고 있으며 점점 더 많은 세계 인구가 온라인 상태이므로 필연적으로 더 많은 애플리케이션을 확장해야하며 모범 사례가 구체화되기 시작합니다. 지식 격차는 AppEngine 및 EC2와 같은 클라우드 서비스와 Cassandra와 같은 오픈 소스 데이터베이스로 인해 양측에서 줄어들 것입니다. 어떤 의미에서 이것은 초기 단계의 병렬 및 비동기 계산과 함께 진행됩니다. 프로그래머가되기에 확실히 매혹적인 시간입니다.


잘못된 가정에서 시작하고 있습니다.

데이터웨어 하우징은 트랜잭션 애플리케이션이 정규화하는 것과 같은 방식으로 데이터를 정규화하지 않습니다. "많은"조인이 없습니다. 상대적으로 적습니다.

특히 데이터웨어 하우스가 거의 업데이트되지 않기 때문에 두 번째 및 세 번째 일반 양식 위반은 "문제"가 아닙니다. 그리고 업데이트 될 때 일반적으로 차원 행을 "현재"대 "현재가 아님"으로 만드는 것은 상태 플래그 만 변경됩니다.

업데이트에 대해 걱정할 필요가 없기 때문에 업데이트가 비정상적인 관계로 이어질 수없는 2NF 수준으로 항목을 분해하지 않습니다. 업데이트가 없다는 것은 이상이 없음을 의미합니다. 분해도없고 조인도 없습니다. 모든 것을 사전 가입 할 수 있습니다.

일반적으로 DW 데이터는 스타 스키마에 따라 분해됩니다. 이렇게하면 측정 값 (단위가있는 숫자)과 차원에 대한 외래 키 참조가 포함 된 숫자 "사실"테이블로 데이터를 분해 할 수 있습니다.

차원 (또는 "비즈니스 항목")은 속성이있는 실제 사물로 생각하는 것이 가장 좋습니다. 종종 여기에는 지역, 시간, 제품, 고객 등과 같은 항목이 포함됩니다. 이러한 항목에는 종종 복잡한 계층 구조가 있습니다. 계층은 일반적으로 임의적이며 다양한 비즈니스보고 요구에 의해 정의되며 별도의 테이블로 모델링되지 않고 집계에 사용되는 차원의 열에 불과합니다.


몇 가지 질문에 답하기 위해.

"이 결합은 사물의 애플리케이션 측면에서 이루어져야합니다". 거의. 데이터는로드되기 전에 "미리 결합"됩니다. 차원 데이터는 종종 해당 차원에 대한 관련 소스 데이터의 조인입니다. 비교적 평평한 구조로 결합되고 적재됩니다.

업데이트되지 않습니다. 업데이트 대신 추가 기록 레코드가 삽입됩니다.

"하지만 비싸기 시작하지 않습니까?". 거의. 데이터를로드하려면 약간의주의가 필요합니다. 그러나보고 / 분석 조인이 많지 않습니다. 데이터는 사전 결합됩니다.

데이터가 사전 결합 되었기 때문에 ORM 문제는 대체로 문제가됩니다. ORM은 적절하게 팩트 또는 차원에 매핑됩니다. 특별한 경우를 제외하고 차원은 작고 메모리에 완전히 맞습니다. 예외는 금융 (은행 또는 보험) 또는 공공 시설에 있고 대규모 고객 데이터베이스가있는 경우입니다. 이러한 고객 차원은 메모리에 거의 맞지 않습니다.


A JOIN는 순수한 관계형 용어이며 모든 데이터베이스가 관계형은 아닙니다.

다른 데이터베이스 모델에는 관계를 구축하는 다른 방법이 있습니다.

네트워크 데이터베이스 find a key - fetch the reference - find a key는 공통 프로그래밍 언어로 프로그래밍해야하는 끝없는 체인을 사용합니다 .

코드는 애플리케이션 측 또는 서버 측에서 실행될 수 있지만, SQL설정 기반이 아니며 심지어 설정 기반이 아닙니다.

적절하게 설계된 네트워크 데이터베이스는 관계형 데이터베이스보다 훨씬 빠를 수 있습니다.

예를 들어, 네트워크 데이터베이스는 다른 엔티티에 대한 참조를 파일의 오프셋에 대한 직접 포인터 또는이 엔티티에 대한 정보가 저장되는 디스크의 블록으로 저장할 수 있습니다.

이를 위해 효율적인 코드를 작성한 경우 네트워크를 더욱 빠르게 탐색 할 수 있습니다.

관계형 데이터베이스는 정수 (또는 더 높은 순서의 트리플 또는 튜플)와 같은 기본 값 쌍으로 만 참조를 저장할 수 있습니다.

관계형 데이터베이스에서 이러한 값을 찾으려면 엔진은 다음을 수행해야합니다.

  • 첫 번째 값을 포함하는 튜플이 어디에 있는지 알아 내십시오.
  • 두 번째 값 찾기
  • Find the address of the root in a B-Tree holding the data the second number refers to
  • Traverse this tree
  • Find the pointer to the actual table (which may be stored as a B-Tree itself, in which case the pointer is the value of the PRIMARY KEY of the row we're after)
  • Find the table's row by the pointer or traverse the table
  • Finally, get the result.

And you can control this only to a certain extent. After than, you just issue the SQL query and wait.

Relational model made to simplify the developer's life, not to achieve the super speed always and no matter what.

This is same as assembly vs. higher-level languages, relational model being a higher-level language.

You may want to read the article in my blog

, in which I try to explain the differences between several commonly used database models.


When you denormalise your data in this manner, you do so to avoid the cost of joining disparate items; you accept that some data may be duplicated and that certain ways of combining it may be difficult, for the performance benefit of using simple queries.

If you're having to do any great amount of joining at the application level, it implies that you haven't denormalised it enough.

Ideally, you'll be able to make one query for any set of data you want. In practice, you shouldn't have to use more than two or three queries for any aspect of your application, and any application-level joining will be more of a trivial retrieval of stuff from the separate resultsets for insertion into the view.

This kind of thing is only really needed for truly massive datasets, and there are all kinds of tradeoffs involved. To give just one example: BigTable can't do aggregate queries, such as giving you a count. It can be used to give you a figure that's roughly accurate - in the sense that if you have, say, 12,149,173 records of which 23,721 were added in the last hour, it doesn't really matter if the best you can find out is that you have "about 12,100,000 records". If your application depends on knowing the precise figure at any given moment, then you shouldn't be using BigTable for it, is the general attitude.


Applications like facebook have very few data changes, most of the time users are posting new items. So the fact that multiply records need updating when a item is changed is a lesser problem.

This lets allows the data not to be normalized without hitting the common problems with updates.

Applications like Amazon can afford to load all the data for a single user into RAM (how big is a shopping cart after all?), then update the data in RAM and write it out as a single data item.

Once again removing the need to have most data normalized.

You are trading scaling for ease of application development, so if you don’t need to scale to great heights you may wish to keep the ease of application development that RDBMS provide.


I think that in these situations you are going to be pretty much on your own and are going to have to roll everything yourself. I've not been there but have considered it for some of our projects. You can get pretty large with relational DBs (as SO demonstrates) so I shall continue to enjoy the relational goodness for now.


Generally, data warehousing is built around using joins and data split into dimensions and fact tables (with so-called "star schemas" etc)

Joins will often be pre-calculated and stored as de-normalized tables.

I'm not aware of any ORM tools that work with database systems which don't allow joins, as these are not generally seen as traditional relational databases.

참고URL : https://stackoverflow.com/questions/1532218/life-without-joins-understanding-and-common-practices

반응형