스타 스키마 데이터웨어 하우스의 동적 필드에 대한 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.