2017-11-06 17 views
0

우리에게는 일련의 장치가 있으며 모두 센서가 있습니다. 모든 장치에는 공통된 센서 세트가 있지만 일부 장치에는 추가 센서가 있습니다. 모든 센서는 서로 다른 이산화 수준을 가지고 있으며 일부 센서는 때때로 매우 빠르게 변할 수 있으며 때때로 약간의 시간 동안 변할 수 없습니다. 예를 들어 , 우리는 위해 기기를 가지고 형태로 패킷들의 스트림을 (NULL 값이 변경되지 않는 것을 의미한다)Clickhouse에 센서 데이터를 저장하는 가장 좋은 방법은 무엇입니까?

Timestamp, Temp, Latitude, Longitude, Speed... 
111, 20, 54.111, 23.111, 10 
112, 20, NULL, NULL, 13 
113, 20, NULL, 23.112, 15 

그리고 DeviceB :

Timestamp, Temp, Latitude, Longitude, Speed..., AdditionalSensor 
111, 24, 54.111, 23.121, 10 ... 1 
112, 23, 55.111, 23.121, 13 ... 2 
113, 23, 55.111, 23.122, 15 ... 1 

몇 시간 후, 새로운 센서있을 어떤 장치에 추가 될 수 있습니다. 모든 센서는 숫자 유형 (Int32, UInt8, Float32) 중 하나 일 수 있습니다.

다음 데이터는 dau, mau, retention, GPS 좌표 클러스터링 등을 계산하는 데 사용됩니다.

우리는 단순히 어떤 테이블 만들 수

:

CREATE TABLE Sensors 
(
     Date Date, 
     Id FixedString(16), 
     DeviceNumber FixedString(16), 
     TimeUtc DateTime, 
     DeviceTime DateTime, 
     Version Int32, 
     Mileage Int32, 
     Longitude Float64, 
     Latitude Float64, 
     AccelX Float64, 
     AccelY Float64, 
     AccelZ Float64 
     ... 
) ENGINE = MergeTree(Date, (DeviceNumber, TimeUtc), 8192); 

하지만, 여기에 두 가지 문제 : 센서 때로는 우리가 어떤 변화의 경우 일부 센서 값에 대한 null 값을 가지고있을 것입니다 다른 세트에 대한 어떤 지원을 타임 스탬프 이전의 마지막 null이 아닌 값을 확인하는 것이 좋습니다.

SensorName, Timestamp, Date, Value 필드가있는 테이블을 생성하면 문제를 해결할 수 있습니다. 그러나 올바른 유형을 선택하는 방법은 무엇입니까? 다른 유형의 테이블을 사용해야합니까? 아마 우리는 흑연 엔진을 사용할 필요가 있습니다. 불행히도, 나는 그 어떤 경험도 가지고 있지 않습니다. 그래서 어떤 도움이 정말로 감사합니다. 센서의 값만 변경하면됩니다.

업데이트 나는 null 값을 처리하는 방법을 방법을 발견했다. 우리는 열 지난 수신 된 값을 요청 "anyLast"기능을 사용할 수 있습니다

SELECT anyLast(Lights) FROM test where TimeUtc <= toDateTime('2017-11-07 11:13:59'); 

불행하게도 우리가 겹치는 윈도우 함수의 일종 (clickhouse 그들에 대한 지원 없음)를 사용하여 누락 된 모든 값을 입력 할 수 없습니다. 따라서 nullable 필드 집계 함수의 경우 null 값만 사용하며 null이 아닌 필드의 경우 0 값을 포함한 모든 값이 사용되며 두 방법이 모두 올바르지 않습니다. 일시적인 해결책은 행의 모든 ​​널 값에 대한 anyLast 값으로 select를 사용하여 삽입하기 전에 널 값을 채우는 것입니다.

답변

1

Clickhouse는 시계열 데이터베이스처럼 사용할 수 있습니다.

테이블 정의로 인해 동적 메트릭이 제한됩니다. 그래서 NULL 값을 처리하려고합니다.

당신은 센서 값이 테이블을 사용할 수

:

여기에 우리가 장치 A의 센서 값로드
CREATE TABLE ts1(
    entity String, 
    ts UInt64, -- timestamp, milliseconds from January 1 1970 
    s Array(String), -- names of the sensors 
    v Array(Float32), -- sensor values 
    d Date MATERIALIZED toDate(round(ts/1000)), -- auto generate date from ts column 
    dt DateTime MATERIALIZED toDateTime(round(ts/1000)) -- auto generate date time from ts column 
) ENGINE = MergeTree(d, entity, 8192) 

:

INSERT INTO ts1(entity, ts, s, v) 
VALUES ('deviceA', 1509232010254, ['temp','lat','long','speed'], [24, 54.111, 23.121, 11]) 

쿼리 위해 기기 온도 데이터 :

SELECT 
    entity, 
    dt, 
    ts, 
    v[indexOf(s, 'temp')] AS temp 
FROM ts1 
WHERE entity = 'deviceA' 

┌─entity─┬──────────────────dt─┬────────────ts─┬─temp─┐ 
│ deviceA│ 2017-10-28 23:06:50 │ 1509232010254 │ 24 │ 
└────────┴─────────────────────┴───────────────┴──────┘ 

확인 자세한 사용법은 this full answer을 참조하십시오.