패턴의 차이를 설명하기 위해 이 페이지의 예시에서는 날씨 풍선이 1분마다 한 번 측정한 값을 기록하는 앱의 데이터를 저장한다고 가정합니다. 동시에 하나 이상의 셀을 작성하는 단일 요청을 의미하기 위해 이벤트를 사용합니다. 위치 ID는 Google Cloud 지역에 해당합니다.
측정
예시
이 페이지의 타임스탬프는 사람이 읽을 수 있도록 'tYYYY-MM-DD-HHMM'과 같은 형식을 가집니다. 프로덕션 테이블에서 타임스탬프는 일반적으로 1970-01-0100:00:00 UTC 이후의 마이크로초 단위로 표시됩니다(예: `1616264288050807`).
압력(파스칼)
94587
온도(섭씨)
9.5
습도(백분율)
65
고도(미터)
601
관련 데이터
예시
풍선 ID
3698
위치
asia-southeast1
타임스탬프1
t2021-03-05-1204
시간 버킷
시간 버킷 패턴에서 테이블의 각 행은 시간, 일 또는 월과 같은 시간의 '버킷'을 나타냅니다. row key에는 week49와 같이 행에 기록된 기간의 타임스탬프가 아닌 식별자와 다른 식별 데이터가 포함됩니다.
분, 시간, 일과 같이 사용하는 버킷의 크기는 사용할 쿼리와 Bigtable 데이터 크기 한도에 따라 다릅니다. 예를 들어 한 시간 분량의 데이터가 포함된 행이 100MB 행당 권장되는 최대 크기보다 크면 30분 또는 1분을 나타내는 행이 더 적합할 수 있습니다.
시간 버킷 패턴의 이점은 다음과 같습니다.
성능이 더 좋습니다. 예를 들어 100개의 측정값을 저장하는 경우 Bigtable은 이러한 측정값이 100개의 행에 있는 것보다 한 행에 있으면 더 빠르게 작성하고 읽습니다.
이러한 방식으로 저장된 데이터는 길고 좁은 테이블의 데이터보다 더 효율적으로 압축됩니다.
단점은 다음과 같습니다.
시간 버킷 스키마 설계 패턴은 단일 타임스탬프 패턴보다 더 복잡하며 개발에 더 많은 시간과 노력이 필요할 수 있습니다.
새 일정에 새 열 추가
이 시간 버킷 패턴에서는 셀 값이 아닌 column qualifier의 데이터를 저장하는 각 이벤트에 대해 행에 새 열을 작성합니다.
즉, 각 셀마다 column family, column qualifier, 타임스탬프를 전송하되 값은 전송하지 않습니다.
샘플 날씨 풍선 데이터에 이 패턴을 사용하면 각 행에 일주일 동안의 단일 날씨 풍선에 대한 pressure와 같은 단일 측정항목의 모든 측정값이 포함됩니다. 각 row key에는 위치, 풍선 ID, 행에서 기록하는 측정항목, 주 번호가 포함됩니다. 풍선이 측정항목의 데이터를 보고할 때마다 행에 새 열을 추가합니다. column qualifier에는 셀 타임스탬프로 식별된 시간(분)의 측정값인 압력(파스칼 단위)이 포함됩니다.
이 시간 패턴에서는 새 이벤트를 기록할 때 기존 열에 새 셀을 추가합니다. 이 패턴을 사용하면 특정 행 및 열에 여러 타임스탬프 셀을 저장할 수 있는 Bigtable의 기능을 활용할 수 있습니다. 이 패턴을 사용할 때 가비지 컬렉션 규칙을 지정하는 것이 중요합니다.
각 지역의 날씨 풍선 데이터를 예로 들어 각 행에는 일주일 동안의 단일 날씨 풍선에 대한 모든 측정값이 포함되어 있습니다. row key 프리픽스는 주의 식별자이므로 단일 쿼리를 사용하여 여러 풍선에 대한 일주일 분량의 데이터를 읽을 수 있습니다. 다른 row key 세그먼트는 풍선이 작동하는 위치와 풍선의 ID 번호입니다. 이 테이블에는 column family가 한 개(measurements) 있고 column family에는 각 측정 유형에 대한 한 열(pressure, temperature, humidity, altitude)이 있습니다.
풍선이 측정값을 전송할 때마다 애플리케이션에서 풍선에 대한 현재 주의 데이터가 포함된 행에 새 값을 작성하며 각 열에 추가 타임스탬프가 추가된 셀을 작성합니다. 주말에 각 행의 각 열에는 주의 1분당 측정값 1개 또는 셀 10,080개(가비지 컬렉션 정책에서 허용하는 경우)가 있습니다.
각 행의 각 열에는 주의 1분당 측정 값이 저장됩니다. 이 경우 3분이 지나면 행의 처음 두 열은 다음과 같이 표시됩니다.
행 키
압력
temp
asia-south2#3698#week1
94558(t2021-03-05-1200)
9.5(t2021-03-05-1200)
94122(t2021-03-05-1201)
9.4(t2021-03-05-1201)
95992(t2021-03-05-1202)
9.2(t2021-03-05-1202)
이 패턴의 사용 사례에는 다음이 포함됩니다.
시간에 따른 측정값의 변화를 측정하려고 합니다.
단일 타임스탬프 행
이 패턴에서는 기존 행의 열에 셀을 추가하는 대신 각 새 이벤트 또는 측정에 대한 행을 만듭니다. row key 서픽스는 타임스탬프 값입니다. 이 패턴을 따르는 테이블은 길고 좁은 경향이 있으며 행의 각 열은 하나의 셀만 포함합니다.
직렬화된 단일 타임스탬프
이 패턴에서는 행의 모든 데이터를 프로토콜 버퍼(protobuf)와 같은 직렬화된 형식으로 단일 열에 저장합니다. 이 방식은 스키마 설계에 자세히 설명되어 있습니다.
예를 들어 이 패턴을 사용하여 날씨 풍선 데이터를 저장하는 경우 4분 후에 테이블이 다음과 같이 표시될 수 있습니다.
행 키
measurements_blob
us-west2#3698#2021-03-05-1200
protobuf_1
us-west2#3698#2021-03-05-1201
protobuf_2
us-west2#3698#2021-03-05-1202
protobuf_3
us-west2#3698#2021-03-05-1203
protobuf_4
이 패턴의 이점은 다음과 같습니다.
스토리지 효율성
속도
단점은 다음과 같습니다.
데이터를 읽을 때 특정 열만 검색할 수 없습니다.
데이터를 읽은 후 역직렬화를 해야 합니다.
이 패턴의 사용 사례에는 다음이 포함됩니다.
어떻게 데이터를 쿼리해야 할지 잘 모르겠으며 쿼리가 변동될 수 있습니다.
Bigtable에서 데이터를 검색하기 전에 데이터를 필터링할 수 있는 것보다 비용을 줄이는 것이 더 중요합니다.
이벤트마다 측정값이 너무 많아서 데이터를 여러 열에 저장하는 경우 행별 한도인 100MB를 초과할 수 있습니다.
비직렬화된 단일 타임스탬프
이 패턴에서는 측정이 하나만 기록되더라도 각 이벤트를 자체 행에 저장합니다. 열의 데이터는 직렬화되지 않습니다.
직렬화된 구조에 데이터를 저장하지 않을 이유가 있으며 모든 열에서 항상 지정된 타임스탬프 범위만 검색하려고 합니다.
이벤트 수를 무제한으로 저장하고 싶습니다
날씨 풍선 예시 데이터를 사용하는 경우 column family와 column qualifier는 시간 버킷과 새 셀을 사용하는 예시와 동일합니다.
그러나 이 패턴에서는 각 날씨 풍선에 보고된 모든 측정 집합이 새 행에 기록됩니다. 다음 패턴은 이 패턴을 사용하여 작성된 5개의 행을 보여줍니다.
행 키
압력
온도
습도
고도
us-west2#3698#2021-03-05-1200
94558
9.6
61
612
us-west2#3698#2021-03-05-1201
94122
9.7
62
611
us-west2#3698#2021-03-05-1202
95992
9.5
58
602
us-west2#3698#2021-03-05-1203
96025
9.5
66
598
us-west2#3698#2021-03-05-1204
96021
9.6
63
624
추가 전략
동일한 데이터 세트에 여러 개의 쿼리를 전송해야 하는 경우 각 테이블에 쿼리 중 하나를 위해 설계된 row key를 사용하여 데이터를 여러 테이블에 저장하는 것이 좋습니다.
경우에 따라 패턴을 결합할 수도 있습니다. 예를 들어 행의 크기가 너무 커지지 않는 한 시간 버킷을 나타내는 행에 직렬화된 데이터를 저장할 수 있습니다.
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-09-04(UTC)"],[[["\u003cp\u003eThis page details various schema design patterns for storing time series data in Bigtable, building upon general schema design concepts.\u003c/p\u003e\n"],["\u003cp\u003eTime series data, which includes measurements and timestamps, can be stored using patterns like time buckets, where rows represent a time period, or single-timestamp rows, where each row represents a single event.\u003c/p\u003e\n"],["\u003cp\u003eTime bucket patterns offer advantages like better performance and data compression but are more complex to design, while single-timestamp patterns can be easier to implement but may lead to performance issues.\u003c/p\u003e\n"],["\u003cp\u003eWithin time buckets, data can be structured by adding new columns for each event, useful when changes in data aren't crucial, or by adding new timestamped cells to existing columns, allowing for change measurement over time.\u003c/p\u003e\n"],["\u003cp\u003eSingle-timestamp rows can utilize serialized or unserialized data storage, with serialized data offering storage efficiency and speed at the cost of flexibility, while unserialized data provides ease of use but reduced performance.\u003c/p\u003e\n"]]],[],null,["# Schema design for time series data\n==================================\n\nThis page describes schema design patterns for storing time series data in\nBigtable. This page builds on [Designing your schema](/bigtable/docs/schema-design) and\nassumes you are familiar with the concepts and recommendations described on that\npage.\n\nA time series is a collection of data that consists of measurements and the\ntimes when the measurements are recorded. Examples of time series include the\nfollowing:\n\n- The plot of memory usage on your computer\n- Temperature over time on a news report\n- Stock market prices over a period of time\n\nA good schema results in excellent performance and scalability, and a bad schema\ncan lead to a poorly performing system. However, no single schema design\nprovides the best fit for all use cases.\n\nThe patterns described on this page provide a starting point. Your unique\ndataset and the queries you plan to use are the most important things to\nconsider as you design a schema for your time-series data.\n\nThe basic design patterns for storing time-series data in\nBigtable are as follows:\n\n- [Rows are time buckets](#time-buckets)\n\n - [New columns for new events](#new-columns)\n - [New cells for new events](#new-cells)\n- [Rows represent single timestamps](#single-timestamp)\n\n - [Serialized column data](#serialized)\n - [Unserialized column data](#unserialized)\n\nData for examples\n-----------------\n\nTo illustrate the differences between patterns, the examples on this page assume\nthat you are storing data for an app that records the\nmeasurements that weather balloons take once every minute. We use *event* to\nmean a single request that writes one or multiple cells at the\nsame time. Location IDs correspond with Google Cloud regions.\n\nTime buckets\n------------\n\nIn a time bucket pattern, each row in your table represents a \"bucket\" of time,\nsuch as an hour, day, or month. A row key includes a non-timestamp identifier,\nsuch as `week49`, for the time period recorded in the row, along with other\nidentifying data.\n\nThe size of the bucket that you use --- such as minute, hour, or day ---\ndepends on the queries that you plan to use and on\n[Bigtable data size limits](/bigtable/quotas#limits-data-size). For example, if\nrows that contain an hour of data are bigger the recommended maximum size\nper row of 100 MB, then rows that represent a half hour\nor a minute are probably a better choice.\n\n**Advantages** of time bucket patterns include the following:\n\n- You'll see better [performance](/bigtable/docs/performance). For example, if you store 100\n measurements, Bigtable writes and reads those measurements faster\n if they are in one row than if they are in 100 rows.\n\n- Data stored in this way is compressed more efficiently than data in tall,\n narrow tables.\n\n**Disadvantages** include the following:\n\n- Time-bucket schema design patterns are more complicated than single-timestamp patterns and can take more time and effort to develop.\n\n### Adding new columns for new events\n\nIn this time bucket pattern, you write a new column to a row for each event,\nstoring the *data in the column qualifier rather than as a cell value*.\nThis means that for each cell, you send the column family, column qualifier, and\ntimestamp, but no value.\n\nUsing this pattern for the sample weather balloon data, each row contains all\nthe measurements for a single metric, such as `pressure`, for a single weather\nballoon, over the course of a week. Each row key contains the location, balloon\nID, metric that you are recording in the row, and a week number. Every time a\nballoon reports its data for a metric, you add a new column to the row. The\ncolumn qualifier contains the measurement, the pressure in Pascals, for the\nminute identified by the cell timestamp.\n\nIn this example, after three minutes a row might look like this:\n\n**Use cases** for this pattern include the following:\n\n- You don't need to measure changes in your time series data.\n\n- You want to save storage space by [using column qualifiers as data](/bigtable/docs/schema-design#columns).\n\n### Adding new cells for new events\n\nIn this time bucket pattern, you add new cells to existing columns when you\nwrite a new event. This pattern lets you take advantage of\nBigtable's ability to let you store multiple timestamped cells in\na given row and column. It's important to specify garbage collection rules when\nyou use this pattern.\n\nUsing the weather balloon data as an example, each row contains all the\nmeasurements for a single weather balloon over the course of a week. The row key\nprefix is an identifier for the week, so you can read an entire week's worth of\ndata for multiple balloons with a single query. The other row key segments are\nthe location where the balloon operates and the ID number for the balloon. The\ntable has one column family, `measurements`, and that column family has one\ncolumn for each type of measurement: `pressure`, `temperature`, `humidity`, and\n`altitude`.\n\nEvery time a balloon sends its measurements, the application\nwrites new values to the row that holds the current week's data for the balloon,\nwriting additional timestamped cells to each column. At the end of the week,\neach column in each row has one measurement for each minute of the week, or\n10,080 cells (if your garbage collection policy allows it).\n\nEach column in each row holds a measurement for each minute of the week. In this\ncase, after three minutes, the first two columns in a row might look like this:\n\n**Use cases** for this pattern include the following:\n\n- You want to be able to measure changes in measurements over time.\n\nSingle-timestamp rows\n---------------------\n\nIn this pattern, you create a row for each new event or measurement instead of\nadding cells to columns in existing rows. The row key suffix is the timestamp\nvalue. Tables that follow this pattern tend to be *tall and narrow*, and each\ncolumn in a row contains only one cell.\n| **Important:** To avoid hotspots, *never* use a timestamp value as a row key prefix.\n\n### Single-timestamp serialized\n\nIn this pattern, you store all the data for a row in a single column in a\nserialized format such as a protocol buffer (protobuf). This approach is\ndescribed in more detail on [Designing your schema](/bigtable/docs/schema-design#query-flux).\n\nFor example, if you use this pattern to store the weather balloon data, your\ntable might look like this after four minutes:\n\n**Advantages** of this pattern include the following:\n\n- Storage efficiency\n\n- Speed\n\n**Disadvantages** include the following:\n\n- The inability to retrieve only certain columns when you read the data\n\n- The need to deserialize the data after it's read\n\n**Use cases** for this pattern include the following:\n\n- You are not sure how you will query the data or your queries might\n fluctuate.\n\n- Your need to keep costs down outweighs your need to be able to filter data\n before you retrieve it from Bigtable.\n\n- Each event contains so many measurements that you might exceed the\n 100 MB per-row limit if you store the data in multiple\n columns.\n\n### Single-timestamp unserialized\n\nIn this pattern, you store each event in its own row, even if you are recording\nonly one measurement. The data in the columns is not serialized.\n\n**Advantages** of this pattern include the following:\n\n- It is generally easier to implement than a time-bucket pattern.\n\n- You might spend less time [refining your schema](/bigtable/docs/schema-design-steps#refine) before using\n it.\n\n**Disadvantages** of this pattern often outweigh the advantages:\n\n- Bigtable is less performant with this pattern.\n\n- Data stored this way is not as efficiently compressed as data in wider\n columns.\n\n- Even when the timestamp is at the end of the row key, this pattern can result\n in hotspots.\n\n**Use cases** for this pattern include the following:\n\n- You want to always retrieve all columns but only a specified range of\n timestamps, but you have a reason not to store the data in a serialized\n structure.\n\n- You want to store an unbounded number of events.\n\nUsing the [weather balloon example data](#example-data), the column family and\ncolumn qualifiers are the same as the example using time buckets and new cells.\nIn this pattern, however, every set of reported measurements for each weather\nballoon is written to a *new row*. The following table shows five rows that are\nwritten using this pattern:\n\nAdditional strategies\n---------------------\n\nIf you need to send multiple different queries for the same dataset, consider\nstoring your data in multiple tables, each with a row key designed for one of\nthe queries.\n\nYou can also combine patterns in some cases. For example, you can store\n[serialized data](#serialized) in rows that represent\n[time buckets](#time-buckets), as long as you don't let the rows become too big.\n\nWhat's next\n-----------\n\n- Review the steps involved in [planning a schema](/bigtable/docs/schema-design-steps).\n- Understand the [best practices for designing a schema](/bigtable/docs/schema-design).\n- Read about [the performance you can expect from Bigtable](/bigtable/docs/performance).\n- Explore the diagnostic capabilities of [Key Visualizer](/bigtable/docs/keyvis-overview)."]]