집계 및 다운샘플링
기본적으로 위젯은 원시 데이터 행을 받습니다. 필터와 일치하는 모든 레코드가 최신순으로 행 제한까지 전달됩니다. 최신 측정값을 보여주는 테이블에는 이것이 정확히 맞지만, 지난 6개월을 보여주는 차트에는 정확히 맞지 않습니다 — 매초 샘플링하는 센서는 그 기간 동안 1,500만 개의 행을 만들어내는데, 폭이 600픽셀인 차트가 그릴 수 있는 것은 기껏해야 600개입니다.
집계는 이 두 가지 문제를 한 번에 해결합니다. 프로젝트 데이터베이스가 일치하는 레코드를 시간 버킷으로 묶어 버킷마다 값 하나를 계산하고, 그 값들만 위젯으로 보냅니다. 1년치 데이터가 수백 개의 점이 되고, 원시 데이터로는 답할 수 없던 질문 — 시간당 평균 온도, 기계별 레코드 수, 오늘의 총 에너지 — 이 평범한 위젯 설정만으로 해결됩니다.
모든 처리는 데이터가 브라우저에 도달하기 전에 데이터베이스 안에서 일어납니다. 위젯에서는 아무것도 계산하지 않으므로, 집계된 위젯은 뒤에 얼마나 많은 이력이 쌓여 있든 실시간성과 속도를 그대로 유지합니다.
집계 켜기
집계는 필터와 동일한 대화 상자, 즉 데이터 바인딩 옆의 필터 아이콘에서 열리는 대화 상자 안에 있습니다. 대화 상자 전체에 대해서는 데이터 바인딩을 참조하세요.
대화 상자의 집계 섹션에서는 두 가지를 선택할 수 있습니다:
- 원시 데이터 행 — 기본값: 레코드가 저장된 그대로 반환됩니다.
- 시간에 따라 집계 — 레코드가 그룹으로 묶여 그룹당 값 하나로 축약됩니다.
시간에 따라 집계로 전환하면 집계 방법 선택기와, 해당되는 경우 아래에서 설명하는 버킷 크기 컨트롤이 나타납니다. 모든 집계에는 대상이 되는 시간 범위가 필요하므로, 위젯에 아직 시간 창이 없었다면 집계를 켤 때 지난 24시간의 기본 롤링 창이 함께 채워집니다 — 바로 위의 롤링 시간 창 섹션에서 조정하세요.
집계 방법
| 집계 방법 | 버킷당 결과 | 적용 대상 |
|---|---|---|
| 평균 | 값들의 산술 평균 | 숫자 컬럼 |
| 합계 | 값들의 총합 | 숫자 컬럼 |
| 개수 | 값이 있는 레코드의 수 | 모든 컬럼 |
| 최솟값 | 가장 작은 값 | 숫자, 텍스트, 타임스탬프 컬럼 |
| 최댓값 | 가장 큰 값 | 위와 동일 |
| 첫 번째 값 | 버킷에서 가장 이른 레코드의 값 | 모든 컬럼 |
| 마지막 값 | 버킷에서 가장 늦은 레코드의 값 | 모든 컬럼 |
하나의 데이터 시리즈에 속한 모든 값 컬럼에는 하나의 집계 방법이 적용됩니다. 같은 측정값에 대해 여러 통계를 보여주려면 — 예를 들어 평균 선과 함께 최솟값/최댓값 밴드를 그리려면 — 통계마다 데이터 시리즈를 하나씩 추가하세요. 이들은 하나의 데이터베이스 쿼리를 공유하므로 시리즈를 추가해도 요청은 늘지 않습니다.
평균, 합계, 최솟값, 최댓값에는 숫자를 담은 컬럼이 필요합니다. 텍스트나 boolean 컬럼을 지정하면 설명 메시지와 함께 거부됩니다. 개수는 어떤 컬럼에서도 동작하므로 “레코드가 몇 개인가” 유형의 질문에 쓰는 방법입니다.
무엇이 집계되는가
집계 대상 컬럼을 직접 나열할 필요는 없습니다 — 플랫폼이 이미 위젯에 설정해 둔 필드 매핑에서 도출합니다:
| 필드 역할 | 집계 시 의미 |
|---|---|
x = tsp | 차트가 시간 축을 가집니다: 버킷이 시간 창을 잘게 나눕니다. |
| x = 그 외의 컬럼 | 차트가 카테고리 축을 가집니다: 해당 컬럼이 레코드를 그룹으로 묶습니다. |
| pivot | 서로 다른 값마다 시리즈를 하나씩 나누어 각각 따로 집계합니다. |
| y, r 및 그 외 값 필드 | 선택한 집계 방법으로 집계됩니다. |
즉, 원시 데이터 행에 쓰던 매핑을 그대로 계속 사용할 수 있습니다. x를 타임스탬프에, y를 temperature에 매핑한 뒤 집계를 켜면, 차트는 개별 측정값 대신 버킷별 평균 온도를 그립니다.
집계된 위젯의 세 가지 형태
1. 자동 해상도의 시계열
가장 흔한 경우입니다: x가 tsp에 매핑되어 있고 버킷 모드가 자동 — 위젯 해상도에 맞춤으로 남아 있는 경우입니다. 이때 플랫폼은 위젯이 렌더링된 폭에서 버킷 크기를 결정합니다 — 폭이 600픽셀인 차트는 시간 창이 얼마이든 약 600개를 넘는 점을 받지 않습니다. 창을 하루에서 1년으로 넓히면 버킷이 그만큼 넓어질 뿐이며, 네트워크를 오가는 데이터 양은 그대로입니다.
버킷 크기 자체에는 의미가 없고 추세를 읽기 좋고 빠르게 보여주기만 하면 될 때 이 방식을 선택하세요: “지난 한 달간의 온도”.
위젯 크기를 조절하면 새 해상도로 다시 조회하지만, 폭이 한 단계를 넘어설 때만 그렇습니다 — 조금씩 끄는 정도로는 요청이 발생하지 않습니다.
2. 고정 버킷 크기의 시계열
고정 버킷 크기를 선택하고 길이와 단위를 지정합니다 — 1시간 간격, 15분 간격, 6시간 간격. 간격이 표시상의 세부 사항이 아니라 질문 자체의 일부일 때 사용하세요: “시간당 생산 수량”, “일별 소비 에너지”.
고정 버킷은 브라우저의 시간대를 기준으로 자연스러운 경계에 정렬됩니다: 6시간 버킷은 현지 시간 00:00, 06:00, 12:00, 18:00에 시작하고, 일 단위 버킷은 현지 자정에 나뉘며, 주 단위 버킷은 월요일에 시작합니다.
선택한 크기가 차트가 합리적으로 보여줄 수 있는 것보다 많은 버킷을 만들어낸다면(상한은 2000개), 플랫폼은 쿼리를 거부하는 대신 요청한 크기의 배수로 버킷을 자동으로 넓힙니다 — 1주일 전체에 대한 1분 버킷은 5분 버킷이 됩니다. 이런 일이 발생하면 대화 상자가 이를 알려주고 실제로 사용되는 크기를 표시합니다.
3. 카테고리당 값 하나
x를 타임스탬프가 아닌 컬럼에 — 기계 이름, 제품 유형, 사이트 등에 — 매핑하면 위젯은 카테고리 요약이 됩니다: 시간 창 전체가 하나의 버킷으로 취급되고, 해당 컬럼의 서로 다른 값마다 집계된 행이 정확히 하나씩 나옵니다.
*“오늘 기계별 레코드 수”*나 *“이번 주 생산 라인별 평균 사이클 타임”*에 쓰는 형태입니다. 선택할 버킷 크기가 없으므로, 대화 상자는 간격 컨트롤을 표시하는 대신 그 사실을 알려줍니다.
레코드 세기: 그룹의 행 수는 타임스탬프 컬럼 tsp에 개수를 적용한 것입니다. 모든 레코드에는 타임스탬프가 있기 때문입니다. y를 tsp에 매핑하면 플랫폼이 자동으로 개수를 선택합니다 — 타임스탬프 컬럼에 허용되는 유일한 집계이기 때문입니다.
x → machine_name (레코드를 그룹으로 묶음)
y → tsp (개수 계산 → 레코드 수)
집계 방법: 개수
시간 창: 지난 1일결과는 각 기계가 지난 하루 동안 만들어낸 레코드 수를 보여주는 기계별 막대 하나입니다.
집계된 단일 값
스칼라 바인딩 — KPI 타일의 값, 게이지, 텍스트 필드 — 에서도 값 섹션에서 같은 선택을 할 수 있습니다:
- 최신 값 — 기존과 동일하게 가장 새로운 레코드의 값.
- 시간 창에 대해 집계 — 시간 창 전체에 대해 계산한 값 하나.
실시간 대표 지표에 사용하세요: “오늘 생산 수량”(1일 시간 창에서 tsp에 개수 적용), “이번 교대의 평균 온도”, “이번 달 최대 전력”. 여기에도 버킷 크기는 없습니다 — 시간 창이 곧 버킷입니다. 새 레코드가 도착하면 값이 갱신되므로, 위젯에 직접 입력한 숫자와 달리 결코 낡지 않습니다.
필터·시간 창·집계의 조합
대화 상자의 섹션들은 표시된 순서대로 적용되며, 이는 데이터베이스가 적용하는 순서이기도 합니다:
- 롤링 시간 창 / 사용자 정의 시간 창 — 기간을 선택합니다.
- 필터 — 그 기간 안에서 어떤 레코드가 참여할지 선택합니다.
- 집계 — 선택된 레코드를 버킷당 값 하나로 축약합니다.
- 행 제한 — 최후의 안전장치입니다. 아래를 참조하세요.
필터가 집계보다 먼저 실행되므로, 필터는 각 버킷에 들어갈 대상을 좁힙니다. machine = 'A'를 시간별 평균과 결합하면 기계 A의 시간별 평균이 나옵니다. 필터 위젯이나 라우팅 세그먼트에 연결된 필터는 원시 데이터 행에서와 똑같이 동작하므로, 집계된 차트도 다른 위젯과 마찬가지로 드롭다운이나 페이지 URL을 따릅니다.
캘린더 위젯도 함께 조합됩니다: 사용자가 날짜 범위를 선택하면 그 범위가 롤링 창을 대체하고 집계도 이를 따릅니다.
시간 창 스냅
집계가 활성화된 동안에는 시간이 흘러도 버킷이 제자리에 머무르도록 시간 창의 시작이 버킷 격자에 스냅됩니다. 그렇지 않으면 새로 고칠 때마다 모든 버킷 경계가 조금씩 밀려 차트 전체가 흔들리게 됩니다. 대화 상자는 이를 *“창이 … 단위로 이동합니다.”*라고 알려주며, 확정된 시작/종료 미리보기에는 실제로 조회되는 범위가 항상 표시됩니다.
시간 창의 끝은 결코 늘어나지 않습니다: 지금까지인 창은 계속 지금까지이고, 한 시간 전까지인 창은 그 마지막 한 시간에 절대 닿지 않습니다.
집계에서의 행 제한
행 제한은 계속 표시되지만 역할이 달라집니다: 버킷 수는 이 필드가 아니라 위젯 크기나 지정한 고정 간격에서 도출됩니다. 이 값은 위젯이 원시 데이터 행으로 되돌아가야 하는 경우 — 예를 들어 플랫폼 버전이 집계 기능보다 오래된 자체 호스팅 인스턴스에서 — 에만 적용됩니다. 적절한 값으로 남겨두면 그런 위젯도 계속 쓸 만한 상태로 유지됩니다.
데이터의 공백
일치하는 레코드가 하나도 없는 버킷은 0으로 반환되는 것이 아니라 결과에서 제외됩니다. 평균에는 이것이 정직한 답입니다 — 아무것도 없는 것의 평균은 존재하지 않기 때문입니다. 하지만 간헐적으로 발생하는 이벤트의 개수 차트에서는, 선 차트가 조용한 구간에서 0으로 떨어지는 대신 직선으로 이어 그린다는 뜻이 됩니다. 막대 차트는 공백을 자연스럽게 보여줍니다. 선 차트에서는 “데이터 없음”과 “0”의 차이를 염두에 두세요.
실시간 업데이트
집계된 위젯도 실시간으로 유지됩니다. 레코드가 도착하면 영향을 받는 버킷이 다시 계산되고 위젯이 갱신됩니다 — 몇 초에 한 번을 넘지 않으므로, 높은 빈도로 발행하는 디바이스가 보드를 마비시킬 수는 없습니다. 가장 새로운 버킷은 대개 아직 채워지는 중이므로 버킷이 닫힐 때까지 값이 계속 바뀝니다. 이는 정상이며, 개수와 합계에서 실시간 차트의 마지막 점이 이웃한 점보다 낮게 보이는 이유이기도 합니다.
성능과 긴 이력
긴 시간 창에 대한 집계라도 그 뒤에 있는 레코드는 읽어야 합니다. 긴 시간 창의 차트를 일상적으로 뒷받침하는 테이블이라면, 앱이 데이터 스키마에 연속 다운샘플링을 선언할 수 있습니다 — 데이터 백엔드 레퍼런스의 downsample을 참조하세요. 그러면 플랫폼이 테이블의 사전 집계된 사본을 유지하면서 긴 시간 창 쿼리를 그 사본으로 응답하므로 보통 수십~수백 배 빨라지고, 그 다운샘플링된 이력을 원시 데이터 자체보다 더 오래 보관할 수도 있습니다 — 원시 레코드가 이미 삭제된 뒤에도 차트가 2년치 시간별 평균을 계속 보여줄 수 있습니다.
이는 보드 입장에서는 완전히 투명합니다: 위젯 설정은 달라지지 않으며, 사전 집계된 사본이 처리할 수 없는 쿼리(아주 미세한 간격, 사본이 그룹으로 묶지 않는 컬럼에 대한 필터)는 자동으로 원시 테이블로 되돌아갑니다.
제한 사항
- 집계는 테이블에 적용되며, 변환 테이블에는 적용되지 않습니다. 대신 기반 테이블을 집계하거나, 변환의 SQL 자체에서 미리 집계하세요.
- 데이터 시리즈당 집계 방법은 하나입니다. 한 컬럼에 대한 여러 통계가 필요하면 데이터 시리즈를 여러 개 사용하세요.
- 타임스탬프는 개수로만 집계됩니다. 타임스탬프의
평균은 의미가 없으므로 거부됩니다. - 하나의 데이터 시리즈에서 카테고리 축과 시간 축은 함께 쓸 수 없습니다 — 차트는 “시간에 따른” 것이거나 “카테고리별”인 것 중 하나입니다. 둘 다 필요하면(기계별 시간 평균)
x는tsp에 그대로 두고 기계 컬럼을 pivot에 넣으세요. - JSON 필드도 일반 컬럼처럼 집계할 수 있지만, 사전 집계된 사본의 이점을 얻는 것은 앱이 다운샘플링 대상으로 선언한 필드뿐입니다. 나머지는 원시 테이블에서 계산됩니다.
레시피
| 원하는 결과 | x | y | 집계 방법 | 간격 |
|---|---|---|---|---|
| 한 달간의 온도 추세 | tsp | temperature | 평균 | 자동 |
| 시간당 생산 수량 | tsp | tsp | 개수 | 고정, 1시간 |
| 일별 소비 에너지 | tsp | kwh | 합계 | 고정, 1일 |
| 기계별 시간당 최대 전력 | tsp | power (+ pivot machine) | 최댓값 | 고정, 1시간 |
| 오늘 기계별 레코드 수 | machine | tsp | 개수 | — (카테고리) |
| 이번 주 라인별 평균 사이클 타임 | line | cycle_time | 평균 | — (카테고리) |
| 오늘 생산 수량 (KPI 타일) | — | tsp | 개수 | — (단일 값) |
요약
- 필터 대화 상자에서 바인딩을 원시 데이터 행에서 시간에 따라 집계로 전환하면, 레코드를 그대로 보내는 대신 데이터베이스가 값을 계산합니다.
x를 타임스탬프에 두면 시계열이 됩니다 — 추세에는 자동 해상도를, 간격 자체가 질문일 때는 고정 간격을 사용하세요.x를 다른 컬럼에 두면 카테고리당 값 하나가 되고, 스칼라 바인딩에서는 실시간 숫자 하나가 됩니다.- 레코드를 세는 방법은
tsp컬럼에 개수를 적용하는 것입니다. - 필터는 집계보다 먼저 적용되고, 빈 버킷은 제외되며, 행 제한은 대체 안전장치가 됩니다.
- 긴 이력의 경우 앱이
downsample을 선언하면, 플랫폼이 사전 집계된 사본으로 차트를 제공하고 원시 데이터 보존 기간을 넘어서까지 그 이력을 보관할 수 있습니다.