테스트 데이터 생성
테스트 데이터 생성 (Generating Test Data)
새로운 사용 사례를 테스트하거나 구현을 벤치마킹할 때 임의 데이터 생성은 유용해요. ClickHouse에는 임의 데이터를 생성하는 다양한 함수가 있어서, 많은 경우 외부 데이터 생성기가 필요하지 않아요. 이 가이드는 서로 다른 무작위성 요구 사항을 가진 무작위 데이터셋을 ClickHouse에서 생성하는 여러 예시를 제공해요.
출처: 문서
본문
단순 균등 데이터셋
사용 사례: 임의 타임스탬프와 이벤트 유형을 가진 사용자 이벤트의 빠른 데이터셋 생성.
CREATE TABLE user_events (
event_id UUID,
user_id UInt32,
event_type LowCardinality(String),
event_time DateTime
) ENGINE = MergeTree
ORDER BY event_time;
INSERT INTO user_events
SELECT
generateUUIDv4() AS event_id,
rand() % 10000 AS user_id,
arrayElement(['click','view','purchase'], toUInt32(rand()) % 3 + 1) AS event_type,
now() - INTERVAL rand() % 3600*24 SECOND AS event_time
FROM numbers(1000000);
rand() % 10000: 10k 사용자의 균등 분포arrayElement(...): 세 이벤트 유형 중 하나를 무작위 선택- 타임스탬프는 지난 24시간에 걸쳐 분포
지수 분포 (Exponential distribution)
사용 사례: 대부분은 낮지만 일부는 높은 구매 금액 시뮬레이션.
CREATE TABLE purchases (
dt DateTime,
customer_id UInt32,
total_spent Float32
) ENGINE = MergeTree
ORDER BY dt;
INSERT INTO purchases
SELECT
now() - INTERVAL randUniform(1,1_000_000) SECOND AS dt,
number AS customer_id,
15 + round(randExponential(1/10), 2) AS total_spent
FROM numbers(500000);
- 최근 기간에 걸친 균등 타임스탬프
randExponential(1/10)— 대부분의 합계가 0 부근이고, 최소값으로 15가 더해짐
시간 분포 이벤트 (Poisson)
사용 사례: 특정 시기(예: 피크 시간)에 몰리는 이벤트 도착 시뮬레이션.
CREATE TABLE events (
dt DateTime,
event_type String
) ENGINE = MergeTree
ORDER BY dt;
INSERT INTO events
SELECT
toDateTime('2022-12-12 12:00:00')
- ((12 + randPoisson(12)) * 3600) AS dt,
'click' AS event_type
FROM numbers(200000);
- 이벤트는 정오를 중심으로 피크를 이루며, Poisson 분포의 편차를 가짐
시간에 따라 변하는 정규 분포
사용 사례: 시간에 따라 변하는 시스템 메트릭(예: CPU 사용량) 모사.
CREATE TABLE IF NOT EXISTS cpu_metrics (
host String,
ts DateTime,
usage Float32
) ENGINE = MergeTree
ORDER BY (host, ts);
INSERT INTO cpu_metrics
SELECT
arrayJoin(['host1','host2','host3']) AS host,
now() - INTERVAL number SECOND AS ts,
greatest(0.0, least(100.0,
(50 + 30 * sin(toUInt32(number) % 86400 / 86400.0 * 2 * pi()))
+ randNormal(0, 10)
)) AS usage
FROM numbers(10000);
usage는 일주기 사인파(sine wave) + 무작위성을 따름- 값은 [0,100]으로 제한
범주형 및 중첩 데이터
사용 사례: 다중 값 관심사를 가진 사용자 프로필 생성.
CREATE TABLE user_profiles (
user_id UInt32,
interests Array(String),
scores Array(UInt8)
) ENGINE = MergeTree
ORDER BY user_id;
INSERT INTO user_profiles
SELECT
number AS user_id,
arrayShuffle(['sports','music','tech'])[1 + rand() % 3 : 1 + rand() % 3] AS interests,
[rand() % 100, rand() % 100, rand() % 100] AS scores
FROM numbers(20000);
- 1–3 사이의 임의 배열 길이
- 관심사마다 사용자별 점수 3개
더 많은 예시는 ClickHouse에서 임의 데이터 생성하기 블로그를 읽어보세요.
임의 테이블 생성
generateRandomStructure 함수는 임의의 스키마로 테스트·벤치마킹·모의 데이터를 만드는 generateRandom 테이블 엔진과 결합할 때 특히 유용해요. 먼저 generateRandomStructure 함수로 임의 구조가 어떻게 생겼는지만 살펴볼게요.
SELECT generateRandomStructure(5);
다음과 같은 것을 볼 수 있을 거예요.
c1 UInt32, c2 Array(String), c3 DateTime, c4 Nullable(Float64), c5 Map(String, Int16)
씨앗(seed)을 사용해 매번 같은 구조를 얻을 수도 있어요.
SELECT generateRandomStructure(3, 42);
c1 String, c2 Array(Nullable(Int32)), c3 Tuple(UInt8, Date)
이제 실제 테이블을 만들고 임의 데이터로 채워 볼게요.
CREATE TABLE my_test_table
ENGINE = MergeTree
ORDER BY tuple()
AS SELECT *
FROM generateRandom(
'col1 UInt32, col2 String, col3 Float64, col4 DateTime',
1, -- seed for data generation
10 -- number of different random values
)
LIMIT 100; -- 100 rows
-- Step 2: Query your new table
SELECT * FROM my_test_table LIMIT 5;
┌───────col1─┬─col2──────┬─────────────────────col3─┬────────────────col4─┐
│ 4107652264 │ &b!M-e;7 │ 1.0013455832230728e-158 │ 2059-08-14 19:03:26 │
│ 652895061 │ Dj7peUH{T │ -1.032074207667996e112 │ 2079-10-06 04:18:16 │
│ 2319105779 │ =D[ │ -2.066555415720528e88 │ 2015-04-26 11:44:13 │
│ 1835960063 │ _@}a │ -1.4998020545039013e110 │ 2063-03-03 20:36:55 │
│ 730412674 │ _}! │ -1.3578492992094465e-275 │ 2098-08-23 18:23:37 │
└────────────┴───────────┴──────────────────────────┴─────────────────────┘
완전히 임의의 테이블을 위해 두 함수를 결합해 볼게요. 먼저 어떤 구조가 나올지 확인해요.
SELECT generateRandomStructure(7, 123) AS structure FORMAT vertical;
┌─structure──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ c1 Decimal64(7), c2 Enum16('c2V0' = -21744, 'c2V1' = 5380), c3 Int8, c4 UUID, c5 UUID, c6 FixedString(190), c7 Map(Enum16('c7V0' = -19581, 'c7V1' = -10024, 'c7V2' = 27615, 'c7V3' = -10177, 'c7V4' = -19644, 'c7V5' = 3554, 'c7V6' = 29073, 'c7V7' = 28800, 'c7V8' = -11512), Float64) │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
이제 그 구조로 테이블을 만들고 DESCRIBE 문으로 무엇이 만들어졌는지 확인해요.
CREATE TABLE fully_random_table
ENGINE = MergeTree
ORDER BY tuple()
AS SELECT *
FROM generateRandom(generateRandomStructure(7, 123), 1, 10)
LIMIT 1000;
DESCRIBE TABLE fully_random_table;
┌─name─┬─type─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
1. │ c1 │ Decimal(18, 7) │ │ │ │ │ │
2. │ c2 │ Enum16('c2V0' = -21744, 'c2V1' = 5380) │ │ │ │ │ │
3. │ c3 │ Int8 │ │ │ │ │ │
4. │ c4 │ UUID │ │ │ │ │ │
5. │ c5 │ UUID │ │ │ │ │ │
6. │ c6 │ FixedString(190) │ │ │ │ │ │
7. │ c7 │ Map(Enum16('c7V4' = -19644, 'c7V0' = -19581, 'c7V8' = -11512, 'c7V3' = -10177, 'c7V1' = -10024, 'c7V5' = 3554, 'c7V2' = 27615, 'c7V7' = 28800, 'c7V6' = 29073), Float64) │ │ │ │ │ │
└──────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
생성된 데이터 샘플을 위해 첫 번째 행을 살펴볼게요.
SELECT * FROM fully_random_table LIMIT 1 FORMAT vertical;
Row 1:
──────
c1: 80416293882.257732 -- 80.42 billion
c2: c2V1
c3: -84
c4: 1a9429b3-fd8b-1d72-502f-c051aeb7018e
c5: 7407421a-031f-eb3b-8571-44ff279ddd36
c6: g̅b�&��rҵ���5C�\�|��H�>���l'V3��R�[��=3�G�LwVMR*s緾/2�J.���6#��(�h>�lە��L^�M�:�R�9%d�ž�zv��W����Y�S��_no��BP+��u��.0��UZ!x�@7:�nj%3�Λd�S�k>���w��|�&��~
c7: {'c7V8':-1.160941256852442}