스타 스키마 데이터웨어 하우스의 동적 필드에 대한 EAV의 대안


13

API 요청 로그를 저장하기 위해 큰 데이터웨어 하우스에서 동적 필드와 값을 지원해야합니다. 사용자 사례는 모든 API 요청 쿼리 문자열을 저장해야하며 나중에 쿼리를 수행 할 수 있어야한다는 것입니다 (따라서 스토리지가 아니라, 그래서 나는 그들을 위해 얼룩을 사용할 수 없습니다)

예 : http://example.com/?action=test&foo=abc&bar=def...

모든 field => value매핑 을 저장해야 합니다. 즉 (action => test), (foo => abc), (bar => def), 필드가 동적이기 때문에 내가 찾은 유일한 해결책은 Entity-Attribute-Value를 사용하는 것입니다. 그러나 사람들은 그것이 매우 나쁜 디자인이라고 계속 말합니다.

따라서 위의 사용 사례를 고려할 때 EAV에 적합한 대안은 무엇입니까?

KAV를 사용하는 현재 스키마

  1. 테이블 requests
    (id, timestamp, uri)
    (1, 149382220, '/')

  2. 테이블 params
    (request_id, key, value)
    (1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')

어떤 제안?

업데이트 : AWS RedShift에서웨어 하우스를 실행합니다.


2
개발자 데이터베이스에서 제안하는 것을 시도하는 데 어떤 문제가 있습니까? 또한 SQL Server에 대해 이야기하고 있습니까? 의 SQL 태그는 꽤 넓다.
Max Vernon

내 질문을 업데이트
하워드

1
어떤 DBMS를 사용하고 있습니까? 일부는 텍스트 인덱싱 기능이 매우 뛰어나므로 요청을 저장하기 위해 "긴 텍스트"필드를 사용하지 않을 것입니다. 그렇게 말하면서, 나는 당신이 제안한 모델을 사용하는 데 아무런 문제가 없을 것입니다. EAV는 엄격한 의미에서이 특정 목적으로 만 사용됩니다. 다시 말하지만, 어떤 종류의 쿼리를 수행해야합니까? 이 모델에 대해 이러한 쿼리를 작성하여 작동하는지 확인하십시오.
Colin 't Hart

1
어떤 RDBMS를 사용하고 있습니까? SQL충분히 구체적이지 않습니다. 두 번 요청을 받았습니다. 나는 세번째입니다.
Erwin Brandstetter

2
RedShift는 PostgreSQL을 기반으로하기 때문에 hstoreor json데이터 유형 을 사용하려고합니다 (또는 jsonb"/ 업그레이드 할 때").
Colin 't Hart

답변:


11

EAV, XML 및 Sparse Columns의 세 가지 솔루션을 생각할 수 있습니다. 후자는 공급 업체별로 다르며 유용하지 않을 수 있습니다.

어떤 방법을 선택하든 원래 요청 데이터를 원시 형식, 테이블 또는 플랫 파일로 저장하는 것이 좋습니다. 새로운 방식으로 데이터를 저장하는 방법을 시도하고, 요청을 분석하는 방식에 실수가있는 경우 데이터를 다시로드 할 수 있으며, 일괄 처리 또는 "빅 데이터"를 사용하여 API 요청을 구문 분석 할 수있는 기회를 제공합니다 데이터웨어 하우스가 데이터를 효율적으로 처리 할 수없는 경우 도구를 사용하십시오.

EAV 고려 사항

위에서 설명한 것처럼 EAV / KVS가 가장 간단한 구현 일 수 있습니다.

불행히도 그것은 또한 매우 비쌀 것입니다-일반적으로 사용되는 키에 대한 효율적인 쿼리를 얻으려면 키 열에 인덱스가 있어야하며, 이는 매우 조각화 될 수 있습니다. 특정 키를 쿼리하면 비용이 많이 듭니다.

관심있는 키 또는 값을 쿼리하기 위해 구체화 된보기 (많은 공급 업체에서 지원)로 EAV 저장소를 지원하여 인덱싱 또는 인덱스 스캔 비용을 줄일 수 있습니다.

XML

대부분의 엔터프라이즈 데이터베이스 시스템은 유효성 검사, 인덱싱 및 정교한 쿼리를 포함하여 매우 성숙한 XML 처리 기능을 제공합니다.

XML로 API 요청을 데이터베이스에로드하면 요청 당 하나의 튜플이 제공되며, 이는 EAV 테이블에 알 수없는 행 수를 갖는 것보다 논리적으로 사용자에게 약간 더 만족스러운 결과를 줄 수 있습니다.

이것이 효율적인지 여부는 RDBMS 공급 업체 및 구현에 따라 크게 달라집니다.

가장 큰 단점은 이것이 원래 요청의 문자열 조작보다 복잡한 데이터를 관리하는 유일한 방법 일 것입니다!

스파 스 열 / 전통적인 테이블

키당 하나의 열을 사용하여 기존 테이블 구조에 데이터를로드 할 수 있습니다.

SQL Server의 스파 스 열 기능은 EAV 저장소의 훌륭한 대안입니다. 스파 스 열이있는 테이블은 최대 30,000 개의 열을 가질 수 있고 스파 스 열의 NULL 값은 테이블에서 공간을 소비하지 않는다는 점을 제외하면 일반 테이블과 거의 동일하게 작동합니다.

이들을 인덱스 된 인덱스 (다른 SQL Server 특정 기능)와 결합하면 몇 가지 특정 열 및 / 또는 값을 자주 쿼리하는 경우 EAV 저장소를 매우 효율적으로 대체 할 수 있습니다.

다른 벤더와 함께 기존 테이블을 사용하는 것이 가능할 수 있습니다. IBM은 테이블 당 700 개가 넘는 열과 Oracle을 약 1000 개 지원하며 압축 또는 Oracle의 후행 널 처리와 같은 기능을 사용하면 API 데이터를 상당히 효율적으로 저장할 수 있습니다.

이 방법의 명백한 단점은 API에 새 키를 추가 할 때 그에 따라 스키마를 조정해야한다는 것입니다.


2
PostgreSQL에서는 XML을 권장하지 않지만 hstore또는 중 하나를 권장합니다 json. 다음 9.4에 jsonb나의 추천이 될 것입니다.
Colin 't Hart

나는 각각의 장단점과 설명 으로이 답변을 좋아합니다. 매우 유익한 정보-Sparse Columns 정보에 감사드립니다. 스파 스 열 접근 방식을 사용하는 EAV의 예를 원합니다.
StixO

9

EAV는 나쁜 디자인이 아닙니다. 그 자체만으로도 상당한 양의 예측이 필요하고 데이터의 양이 증가함에 따라 성능 문제가 발생할 수 있습니다. 시스템에 적합 할 수도 있습니다.

쿼리 문자열을 저장하기위한 시스템을 설계 할 때 어떤 필드에 관심이 있는지 미리 몰랐습니다. 쿼리 문자열을 직렬화 된 이진 형식으로 저장할 테이블을 만들고 쿼리를 분리 할 수있는 시스템을 만들었습니다. 내가 관심있는 부분을 알고 나면 구성 요소 조각으로 묶습니다. 거기서부터 일련의 테이블을 만들었습니다. 쿼리 문자열 내에 일반적으로 포함 된 데이터 세트에 대해 하나씩.

예를 들어, 결국 리퍼러 데이터 테이블, 대상 요청 데이터 테이블 및 입력 한 검색어와 같은 사용자 관련 항목 테이블이있었습니다.

전체 쿼리 문자열을 단일 테이블에 BLOB으로 저장하는 기능을 발견했지만 나중에 해당 Blob을 분리하는 기능을 제공하여 내 요구를 매우 잘 충족했습니다.


1
질문과 답변 모두에서 이항 긴 객체 BLOB를 의미 하는 용어 가 사용됩니다 . 내가 사용하는 것을 선호 것 처럼 (문자 긴 개체) 또는 뭔가를 우리가 문자가 아닌 이진 데이터에 대해 이야기하고 있기 때문에, PostgreSQL을에. CLOBtext
Colin 't Hart

2
실제로 전체 세션 객체를 직렬화하고 전체를 데이터베이스에 저장했기 때문에 이진 필드를 사용했습니다.
Max Vernon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.