수십억 행의 데이터를위한 최고의 데이터베이스 및 테이블 디자인


74

대량의 전기 및 온도 데이터를 저장하고 분석 해야하는 응용 프로그램을 작성 중입니다.

기본적으로 나는 지난 몇 년 동안 그리고 수십 년 동안 수십 년 동안 다가올 많은 시간당 전력 사용량 측정치를 저장 한 다음 데이터를 매우 복잡한 방식으로 분석해야합니다.

저장해야 할 정보는 현재 위치 ID, 타임 스탬프 (날짜 및 시간), 온도 및 전기 사용량입니다.

저장해야 할 데이터의 양에 대해서는 근사치이지만
20000 개 이상의 위치, 한 달에 720 개 레코드 (시간 측정, 매월 약 720 시간), 120 개월 (10 년 전) )와 미래에 몇 년. 간단한 계산으로 다음과 같은 결과가 나타납니다.

20,000 개 위치 x 720 개 레코드 x 120 개월 (10 년 전) = 1,728,000 개 레코드 .

이들은 과거 레코드이며, 새 레코드는 매달 가져 오기 때문에 한 달에 약 20 000 x 720 = 14,400,000 개의 새 레코드입니다 .

총 위치도 꾸준히 증가 할 것입니다.

모든 데이터에서 다음 작업을 실행해야합니다.

  1. 특정 날짜 및 기간에 대한 데이터를 검색하십시오. 날짜 01.01.2013과 01.01.2017 사이 및 07:00과 13:00 사이의 특정 위치 ID에 대한 모든 레코드.
  2. 특정 날짜 및 시간 범위에 대한 간단한 수학 연산 (예 : 7:00, 13:00 사이에 5 년 동안 특정 위치 ID의 MIN, MAX 및 AVG 온도 및 전기 사용량)

데이터는 매월 작성되지만 수백 명의 사용자가 (적어도) 지속적으로 읽으므로 읽기 속도가 훨씬 더 중요합니다.

NoSQL 데이터베이스에 대한 경험이 없지만 수집 한 것 중에서 여기에서 사용하는 가장 좋은 솔루션입니다. 가장 많이 사용되는 NoSQL 데이터베이스를 읽었지만, 상당히 다르고 테이블 아키텍처도 매우 다르기 때문에 사용할 최상의 데이터베이스를 결정할 수 없었습니다.

내 주요 선택은 Cassandra와 MongoDB 였지만 큰 데이터와 NoSQL에 관해서는 지식이 거의없고 실제 경험이 없기 때문에 확실하지 않습니다. 또한 PostreSQL도 이러한 양의 데이터를 잘 처리합니다.

내 질문은 다음과 같습니다.

  1. 그런 대량의 데이터에 NoSQL 데이터베이스를 사용해야합니까? 그렇지 않다면 MySQL을 고수 할 수 있습니까?
  2. 어떤 데이터베이스를 사용해야합니까?
  3. 특정 시간과 날짜 기간 동안 데이터를 신속하게 검색하고 처리하기 위해 날짜와 시간을 별도의 색인화 된 (가능한 경우) 열에 보관해야합니까, 아니면 타임 스탬프를 단일 열에 유지하여이를 수행 할 수 있습니까?
  4. 시계열 데이터 모델링 접근법이 여기에 적합합니까? 그렇지 않으면 훌륭한 테이블 디자인에 대한 포인터를 줄 수 있습니까?

감사합니다.


29
2017. 작지는 않지만 적절한 하드웨어에 대한 대량의 데이터는 특히 아닙니다. 그리고 나는 당신에게 말하기를 싫어하지만 지금까지 당신이 가지고있는 것은 관계형 데이터처럼 들립니다.
TomTom

6
좋은 키 (에포크 날짜), 압축, 파티셔닝 및 쿼리 / 인덱스의 파티션 정렬을 사용하여 MS SQL Server 2008-2014에 수 천억 개의 행이있는 멀티 TB 테이블을 저장했습니다. 페타 바이트의 데이터를 가져 와서 다르게 분석하고 색인을 생성하기 시작했을 때 NoSQL (Hadoop)으로 이동해야했습니다. NoSQL은 다른 고려 사항이 있어야하며이 경우에는 맞지 않는 것 같습니다.
Ali Razeghi

3
@AliRazeghi Hadoop은 SQL 또는 NoSQL과 아무 관련이 없으며 스토리지 엔진 일뿐입니다. 하둡이 지원하는 많은 SQL 인터페이스가 있습니다.
mustaccio

3
소프트웨어 / 라이센스에 소비해야 할 제약은 무엇입니까?
user3067860

1
무한한 돈이 있으면 SAP HANA 어플라이언스를 구입하는 것이 좋습니다. 대규모 데이터 세트에 대한 집계에 좋습니다. 그러나 당신은 아마도 무한한 돈이 없었을 것입니다.
Philipp

답변:


90

이것은 시간당 데이터를 사용하는 대신 5 분 데이터를 사용하는 것을 제외하고는 매일 매일하는 일입니다. 매일 약 2 억 건의 레코드를 다운로드하므로 여기서 말하는 양은 문제가되지 않습니다. 5 분 데이터의 크기는 약 2TB이며 날씨 데이터는 위치별로 시간 단위로 50 년 전으로 되돌아갑니다. 내 경험을 바탕으로 질문에 대답하겠습니다.

  1. 이를 위해 NoSQL을 사용하지 마십시오. 데이터는 고도로 구조화되어 있으며 관계형 데이터베이스에 완벽하게 맞습니다.
  2. 개인적으로 SQL Server 2016을 사용하고 있으며 해당 양의 데이터에서 계산을 적용하는 데 아무런 문제가 없습니다. 작업을 시작할 때 원래 PostgreSQL 인스턴스에 있었고 작은 AWS 인스턴스에서와 같이 데이터 볼륨을 처리 할 수 ​​없었습니다.
  3. 나는 것이 매우 날짜의 시간 부분을 추출하고 날짜 자체에서 분리 저장하는 것을 권장합니다. 나를 믿어 내 실수에서 배우십시오!
  4. 나는 대부분의 데이터를 목록 방식으로 저장하지만 (DATE, TIME, DATAPOINT_ID, VALUE) 사람들이 데이터를 해석하려는 방식이 아닙니다. 데이터와 방대한 양의 피벗에 대한 끔찍한 쿼리에 대비하십시오. 너무 커서 결과를 계산하기에 비정규 화 된 테이블을 즉시 생성 할 수 있습니다.

일반적인 팁 : 두 데이터베이스 사이에 대부분의 데이터를 저장합니다. 첫 번째는 일직선 시계열 데이터이며 정규화되었습니다. 두 번째 데이터베이스는 비정규 화되었으며 사전 집계 된 데이터를 포함합니다. 필자의 시스템 속도는 사용자가 30 초 동안 보고서가로드되기를 원치 않는다는 사실에 눈이 멀지 않습니다. 개인적으로 2TB의 데이터를 크런치하는 데 30 초가 걸린다고 생각하더라도 말입니다.

날짜와 별도로 시간을 저장하도록 권장하는 이유를 자세히 설명하기 위해 몇 가지 이유는 다음과 같습니다.

  1. 전기 데이터가 표시되는 방식은 Hour Ending입니다따라서 01:00은 실제로 이전 시간의 전력 평균이며 00:00은 시간 종료 24입니다. (24 시간 값을 포함하려면 실제로 두 날짜를 검색해야하기 때문에 중요합니다. 그러나 다음 날의 첫 번째 표시를 더한 것입니다.) 그러나 날씨 데이터는 실제로 앞으로 표시됩니다 (실제 및 다음 시간 예측). 이 데이터에 대한 경험에서 소비자는 날씨가 전력 가격 / 수요에 미치는 영향을 분석하려고합니다. 정리 날짜 비교를 사용하는 경우 타임 스탬프가 동일하더라도 실제로 이전 시간의 평균 가격과 다음 시간의 평균 온도를 비교하는 것입니다.DATETIME 기둥.
  2. 공연. 필자가 생성 한 보고서의 90 % 이상이 그래프라고 말하며 일반적으로 단일 날짜 또는 날짜 범위에 대해 시간에 대한 가격을 표시합니다. 날짜에서 시간을 분리해야하는 경우보고자하는 날짜 범위에 따라 보고서를 생성하는 데 사용되는 쿼리 속도가 느려질 수 있습니다. 소비자가 지난 30 년 동안 연도 별 단일 날짜를보고 싶어하는 경우는 드문 일이 아닙니다 (사실 날씨의 경우 30 년 법선을 생성하는 데 필요합니다) – 이것은 느릴 수 있습니다. 물론 쿼리를 최적화하고 인덱스를 추가 할 수 있으며 믿을 수없는 미친 인덱스가 있지만 시스템을 빠르게 실행할 수 있습니다.
  3. 생산력. 같은 코드 조각을 두 번 이상 작성해야하는 것이 싫습니다. 시간 부분을 추출하기 위해 동일한 쿼리를 반복해서 작성해야 할 때까지 동일한 열에 날짜와 시간을 저장했습니다. 잠시 후, 나는 방금 이것을 해야하는 것을 아프게하고 그것을 자신의 칼럼으로 추출했습니다. 코드를 적게 작성할수록 오류가 발생할 가능성이 줄어 듭니다. 또한 적은 코드를 작성해야 보고서를 더 빨리 가져올 수 있으며 하루 종일 보고서를 기다리는 것을 원하지 않습니다.
  4. 최종 사용자. 모든 최종 사용자가 고급 사용자 인 것은 아닙니다 (즉, SQL 작성 방법을 알고 있음). 최소한의 노력으로 Excel (또는 다른 유사한 도구)로 가져올 수있는 형식으로 데이터를 저장하면 사무실의 영웅이됩니다. 사용자가 데이터에 쉽게 액세스하거나 조작 할 수 없으면 시스템을 사용하지 않습니다. 나를 믿어, 나는 2 년 전에 완벽한 시스템을 설계했고 아무도 이런 이유로 그것을 사용하지 않았다. 데이터베이스 디자인은 사전 정의 된 규칙 / 지침을 준수하는 것이 아니라 시스템을 사용 가능하게 만드는 것입니다.

위에서 말했듯이, 이것은 모두 개인적인 경험을 바탕으로 한 것이며, 몇 년이 지났고 현재 위치로 돌아 가기 위해 많은 재 설계가 이루어졌습니다. 내가 한 일을하지 말고 실수를 통해 배우고 데이터베이스에 대한 결정을 내릴 때 시스템의 최종 사용자 (또는 개발자, 보고서 작성자 등)를 참여시켜야합니다.


Epoch 날짜를 사용하여 행운을 얻었지만 권장 사항은 사용 사례에 흥미 롭습니다. 공유해 주셔서 감사합니다.
Ali Razeghi

원래 날짜 / 시간을 UTC로 저장했지만 소비자는 항상 현지 시간으로 조정해야하므로 불만을 표시했습니다. 궁극적으로 소비자가 데이터를보다 쉽게 ​​사용할 수 있도록 디자인이 변경되었습니다.
Mr.Brownstone

4
나는 이것의 많은 것에 동의하지 않습니다. 여기서 실제 숫자로 보여지는 것처럼 현대 데이터베이스에 대한 실제 관심사 는 없습니다 . 데이터 사용자가 SQL을 사용하기에 너무 어리 석다면 인터페이스를 만들어야합니다. 시간을 추출하는 것은 나쁜 생각입니다
Evan Carroll

1
하드웨어는 어떻습니까?
kennes

1
서비스를 제공하는 사용자 수에 따라 놀라운 하드웨어입니다. 이것은 의사 최적화 응답이므로 귀하의 기술을 포함시키는 것이 유용하다고 생각합니다. 30 초 만에 2TB를 크 런킹 할 수 있다는 소식에 완전히 충격을 받았습니다. 내 자신의 판단은 제쳐두고, 시계열 데이터를 최적화하려는 미래의 사람들에게 유용 할 것이라고 생각합니다!
kennes

57

PostgreSQL 및 BRIN 인덱스

직접 테스트 해보십시오. 이것은 ssd가 장착 된 5 년 된 랩탑에서는 문제가되지 않습니다.

EXPLAIN ANALYZE
CREATE TABLE electrothingy
AS
  SELECT
    x::int AS id,
    (x::int % 20000)::int AS locid,  -- fake location ids in the range of 1-20000
    now() AS tsin,                   -- static timestmap
    97.5::numeric(5,2) AS temp,      -- static temp
    x::int AS usage                  -- usage the same as id not sure what we want here.
  FROM generate_series(1,1728000000) -- for 1.7 billion rows
    AS gs(x);

                                                               QUERY PLAN                                                               
----------------------------------------------------------------------------------------------------------------------------------------
 Function Scan on generate_series gs  (cost=0.00..15.00 rows=1000 width=4) (actual time=173119.796..750391.668 rows=1728000000 loops=1)
 Planning time: 0.099 ms
 Execution time: 1343954.446 ms
(3 rows)

따라서 테이블을 만드는 데 22 분이 걸렸습니다. 테이블이 보통 97GB이기 때문에 주로 그렇습니다. 다음으로 색인을 만듭니다.

CREATE INDEX ON electrothingy USING brin (tsin);
CREATE INDEX ON electrothingy USING brin (id);    
VACUUM ANALYZE electrothingy;

인덱스도 작성하는 데 시간이 오래 걸렸습니다. 그들은 BRIN이기 때문에 2-3MB에 불과하며 쉽게 램에 저장합니다. 96GB를 읽는 것은 순간적이지는 않지만 워크로드에서 랩톱에 실제로 문제가되는 것은 아닙니다.

이제 우리는 그것을 쿼리합니다.

explain analyze
SELECT max(temp)
FROM electrothingy
WHERE id BETWEEN 1000000 AND 1001000;
                                                                 QUERY PLAN                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=5245.22..5245.23 rows=1 width=7) (actual time=42.317..42.317 rows=1 loops=1)
   ->  Bitmap Heap Scan on electrothingy  (cost=1282.17..5242.73 rows=993 width=7) (actual time=40.619..42.158 rows=1001 loops=1)
         Recheck Cond: ((id >= 1000000) AND (id <= 1001000))
         Rows Removed by Index Recheck: 16407
         Heap Blocks: lossy=128
         ->  Bitmap Index Scan on electrothingy_id_idx  (cost=0.00..1281.93 rows=993 width=0) (actual time=39.769..39.769 rows=1280 loops=1)
               Index Cond: ((id >= 1000000) AND (id <= 1001000))
 Planning time: 0.238 ms
 Execution time: 42.373 ms
(9 rows)

타임 스탬프로 업데이트

여기에서 타임 스탬프 열에 대한 인덱스 및 검색 요청을 만족시키기 위해 서로 다른 타임 스탬프가있는 테이블을 생성 합니다. 트랜잭션에 대해 캐시 된 to_timestamp(int)것보다 상당히 느리기 때문에 생성 시간이 조금 더 걸립니다.now()

EXPLAIN ANALYZE
CREATE TABLE electrothingy
AS
  SELECT
    x::int AS id,
    (x::int % 20000)::int AS locid,
    -- here we use to_timestamp rather than now(), we
    -- this calculates seconds since epoch using the gs(x) as the offset
    to_timestamp(x::int) AS tsin,
    97.5::numeric(5,2) AS temp,
    x::int AS usage
  FROM generate_series(1,1728000000)
    AS gs(x);

                                                               QUERY PLAN                                                                
-----------------------------------------------------------------------------------------------------------------------------------------
 Function Scan on generate_series gs  (cost=0.00..17.50 rows=1000 width=4) (actual time=176163.107..5891430.759 rows=1728000000 loops=1)
 Planning time: 0.607 ms
 Execution time: 7147449.908 ms
(3 rows)

이제 타임 스탬프 값으로 쿼리를 실행할 수 있습니다.

explain analyze
SELECT count(*), min(temp), max(temp)
FROM electrothingy WHERE tsin BETWEEN '1974-01-01' AND '1974-01-02';
                                                                        QUERY PLAN                                                                         
-----------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=296073.83..296073.84 rows=1 width=7) (actual time=83.243..83.243 rows=1 loops=1)
   ->  Bitmap Heap Scan on electrothingy  (cost=2460.86..295490.76 rows=77743 width=7) (actual time=41.466..59.442 rows=86401 loops=1)
         Recheck Cond: ((tsin >= '1974-01-01 00:00:00-06'::timestamp with time zone) AND (tsin <= '1974-01-02 00:00:00-06'::timestamp with time zone))
         Rows Removed by Index Recheck: 18047
         Heap Blocks: lossy=768
         ->  Bitmap Index Scan on electrothingy_tsin_idx  (cost=0.00..2441.43 rows=77743 width=0) (actual time=40.217..40.217 rows=7680 loops=1)
               Index Cond: ((tsin >= '1974-01-01 00:00:00-06'::timestamp with time zone) AND (tsin <= '1974-01-02 00:00:00-06'::timestamp with time zone))
 Planning time: 0.140 ms
 Execution time: 83.321 ms
(9 rows)

결과:

 count |  min  |  max  
-------+-------+-------
 86401 | 97.50 | 97.50
(1 row)

따라서 83.321ms에서 1.7 십억 행이있는 테이블에서 86,401 개의 레코드를 집계 할 수 있습니다. 합리적이어야합니다.

시간 종료

시간 종료를 계산하는 것도 매우 쉽습니다. 타임 스탬프를 자른 다음 한 시간 만 추가하면됩니다.

SELECT date_trunc('hour', tsin) + '1 hour' AS tsin,
  count(*),
  min(temp),
  max(temp)
FROM electrothingy
WHERE tsin >= '1974-01-01'
  AND tsin < '1974-01-02'
GROUP BY date_trunc('hour', tsin)
ORDER BY 1;
          tsin          | count |  min  |  max  
------------------------+-------+-------+-------
 1974-01-01 01:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 02:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 03:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 04:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 05:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 06:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 07:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 08:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 09:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 10:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 11:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 12:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 13:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 14:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 15:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 16:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 17:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 18:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 19:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 20:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 21:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 22:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 23:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-02 00:00:00-06 |  3600 | 97.50 | 97.50
(24 rows)

Time: 116.695 ms

집계에서 인덱스를 사용하지는 않지만 가능하다는 점에 유의해야합니다. 그것이 일반적으로 쿼리라면 BRIN을 원할 것입니다. 불변하지 않는 date_trunc('hour', tsin)작은 문제가 date_trunc있기 때문에 먼저 그것을 감싸 야합니다.

파티셔닝

PostgreSQL에 대한 또 다른 중요한 정보는 PG 10이 파티셔닝 DDL을 가져온다는 것입니다 . 예를 들어 매년 파티션을 쉽게 만들 수 있습니다. 겸손한 데이터베이스를 작은 데이터베이스로 나누십시오. 그렇게 할 때 BRIN 대신에 더 빠른 btree 인덱스를 사용하고 유지 관리 할 수 ​​있어야합니다.

CREATE TABLE electrothingy_y2016 PARTITION OF electrothingy
    FOR VALUES FROM ('2016-01-01') TO ('2017-01-01');

또는 무엇이든.


13

@EvanCarroll이 그의 훌륭한 공헌을 할 때까지는 벤치마킹에 대해 언급 한 사람이 아무도 없습니다 .

내가 당신이라면, 나는 시스템을 설정하고, 당신이 생각하는 것을 실행 (최종 사용자 입력을 얻으십시오!)하는 데 가장 많은 10 가지 질문을하는 데 시간을 할애 할 것입니다.

내 생각 :

NoSQL 솔루션은 특정 사용 사례에서는 매우 잘 작동하지만 임시 쿼리에는 유연성이없는 경우가 많습니다. Brian Aker (전 MySQL 수석 아키텍트)의 NoSQL에 대한 재미있는 정보는 여기를 참조 하십시오 !

귀하의 데이터가 관계형 솔루션에 적합하다는 점에 @ Mr.Brownstone에 동의합니다 (이 의견은 Evan Carroll에 의해 확인되었습니다 ).

내가 어떤 비용을 지출한다면 그것은 내 디스크 기술 일 것이다! 거의 쓸 수없는 집계 데이터를 보유하기 위해 NAS 또는 SAN 또는 일부 SSD 디스크에 내가 가진 돈을 쓸 것입니다!

먼저 내가 사용할 수있는 것을 보는 것입니다 지금 . 몇 가지 테스트를 실행하고 결과를 의사 결정자에게 보여주십시오. 이미 EC 작업 형식의 프록시 가 있습니다 ! 그러나 빠른 테스트 또는 두 개의 하드웨어를 함께 사용하면 더 설득력이 있습니다!

그런 다음 돈을 쓰는 것에 대해 생각하십시오! 돈을 쓰려면 소프트웨어보다는 하드웨어를 먼저보십시오. AFAIK, 평가판 기간 동안 디스크 기술을 사용하거나 클라우드에서 몇 가지 개념 증명을 시작할 수 있습니다.

이와 같은 프로젝트에 대한 내 개인적인 첫 번째 호출 포트는 PostgreSQL입니다. 그것은 내가 독점적 인 솔루션을 배제한다고 말할 수는 없지만 물리 법칙과 디스크 법칙은 모두에게 동일합니다! "Yae cannae 비트 법칙 물리학 짐":-)


6

아직 시계열 DBMS를 살펴 보지 마십시오. 기본 초점이 날짜 / 시간 유형 인 데이터를 저장하고 쿼리하는 데 최적화되어 있기 때문입니다. 일반적으로 시계열 데이터베이스는 분 / 초 / 초 단위로 데이터를 기록하는 데 사용되므로 시간 단위로 여전히 적합한 지 확실하지 않습니다. 즉, 이러한 유형의 DBMS는 조사 할 가치가있는 것으로 보입니다. 현재 InfluxDB는 가장 널리 사용되고 널리 사용되는 시계열 데이터베이스 인 것 같습니다.


1
시계열 DBMS의 예는 무엇입니까?
감독

2
봐 가지고 여기를 .
Vérace

4

분명히 이것은 NoSQL 문제가 아니지만 RDBMS 솔루션이 작동하는 동안 OLAP 접근 방식이 훨씬 더 적합하고 관련된 매우 제한된 데이터 범위를 고려할 때 열 기반 DB의 사용을 조사하는 것이 좋습니다. 오히려 행 기반 하나. 이런 식으로 생각하면 17 억 개의 데이터가있을 수 있지만 가능한 모든 시간 또는 월 값을 인덱싱하려면 여전히 5 비트 만 필요합니다.

Sybase IQ (현재 SAP IQ)를 사용하여 시간당 최대 3 억 개의 카운터를 통신 장비 성능 관리 데이터를 저장하는 데 사용하는 비슷한 문제 영역에 대한 경험이 있지만 그러한 솔루션에 대한 예산이 있는지는 의문입니다. 오픈 소스 분야에서 MariaDB ColumnStore는 매우 유망한 후보이지만 MonetDB도 조사하는 것이 좋습니다.

쿼리 성능이 중요한 동인이므로 쿼리의 구문을 고려해야합니다. OLAP과 RDBMS의 가장 큰 차이점은 다음과 같습니다. OLAP을 사용하면 쿼리 성능을 표준화하고 반복을 줄이거 나 스토리지를 줄이거 나 일관성을 유지하지 않습니다. 따라서 원래 타임 스탬프 (시간대를 캡처해야한다는 것을 기억 했습니까?) 외에도 UTC 타임 스탬프에 대한 별도의 필드가 있고 날짜 및 시간에 대한 다른 필드가 있으며 년, 월, 일, 시간, 분에 대한 필드가 있습니다. 그리고 UTC 오프셋. 위치에 대한 추가 정보가있는 경우 필요시 찾아 볼 수있는 별도의 위치 테이블에 해당 위치를 유지하고 주 레코드에서 해당 테이블의 키를 유지하되 주 테이블의 전체 위치 이름은 다음과 같이 유지하십시오. 글쎄, 결국

마지막 제안으로, 인기있는 집계 데이터에 대해 별도의 테이블을 사용하고 일괄 작업을 사용하여 집계합니다. 이렇게하면 집계 된 값을 사용하고 현재와 과거 또는 과거를 비교하는 쿼리를 만드는 각 보고서마다 연습을 반복 할 필요가 없습니다. 역사적에서 역사적으로 훨씬 더 쉽고 훨씬 빠릅니다.


Greenplum 을 원한다면 기둥 형 상점으로 생각할 수도 있습니다 ! "보너스"로서-PostgreSQL을 기반으로합니다!
Vérace 2009 년

HP Vertica에 대한 경험이 풍부합니다. 많은 조정없이 1,300 억 개의 행이있는 9 개의 열이있는 단일 테이블이있었습니다. 방금 작동했습니다.
ThatDataGuy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.