学习ClickHouse数据库,通常需要下载官网一些示例数据。我们也可以通过内置函数
generateRandom
快速生成测试数据,从而测试学习一些特性的性能及底层原理。
函数语法
generateRandom函数基于给定schema生成随机数据,用于填充测试表。不是所有类型都支持。
generateRandom('name TypeName[, name TypeName]...', [, 'random_seed'[, 'max_string_length'[, 'max_array_length']]])
- name — 列名称.
- TypeName — 列类型.
- max_array_length — 所有生成arrays或maps最大元素,默认为10.
- max_string_length — 生成字符串的最大长度,默认为10.
- random_seed — 手动指定随机种子,为null则随机生成.
返回与schema对应的表对象。
举例:
SELECT * FROM generateRandom('a Array(Int8), d Decimal32(4), c Tuple(DateTime64(3), UUID)', 1, 10, 2) LIMIT 3;
上面示例生成三个字段schema数据,可选参数中第一个是随机种子,第二个最大字符串长度,第三个最大数组长度,执行SQL返回结果:
┌─a────────┬────────────d─┬─c──────────────────────────────────────────────────────────────────┐
│ [77] │ -124167.6723 │ ('2061-04-17 21:59:44.573','3f72f405-ec3e-13c8-44ca-66ef335f7835') │
│ [32,110] │ -141397.7312 │ ('1979-02-09 03:43:48.526','982486d1-5a5d-a308-e525-7bd8b80ffa73') │
│ [68] │ -67417.0770 │ ('2080-03-12 14:17:31.269','110425e5-413f-10a6-05ba-fa6b3e929f15') │
└──────────┴──────────────┴────────────────────────────────────────────────────────────────────┘
也可以先创建表,然后插入随机生成数据:
CREATE TABLE random (a Array(Int8), d Decimal32(4), c Tuple(DateTime64(3), UUID)) engine=Memory;
INSERT INTO random SELECT * FROM generateRandom() LIMIT 2;
SELECT * FROM random;
返回结果:
┌─a────────────────────────────┬────────────d─┬─c──────────────────────────────────────────────────────────────────┐
│ [] │ 68091.8197 │ ('2037-10-02 12:44:23.368','039ecab7-81c2-45ee-208c-844e5c6c5652') │
│ [8,-83,0,-22,65,9,-30,28,64] │ -186233.4909 │ ('2062-01-11 00:06:04.124','69563ea1-5ad1-f870-16d8-67061da0df25') │
└──────────────────────────────┴──────────────┴────────────────────────────────────────────────────────────────────┘
生成压力测试数据
SELECT * FROM generateRandom('a UUID, b DateTime, c Text', NULL, 2048) LIMIT 1000;
这里保持随机种子为null,字符串长度为2048,即最大长度。
下面示例利用测试数据进行压力测试,生成1亿数据量:
INSERT INTO test_stress
SELECT * FROM generateRandom('ID Int64, test_until_2k Text',1,2048) LIMIT 100000000;
随机数据分布
均匀分布
均匀分布默认数据范围为[0,1), 也可以通过参数指定数据范围:
SELECT randUniform(5,10)
如果需要整数,可以使用下面语句,生成[5,9]返回的整数:
SELECT floor(randUniform(5, 10)) AS r
非均匀分布
首先最常用的应该是正太分布:
SELECT randNormal(100, 5) -- 100 为均值,5是标准差
示例:
SELECTfloor(randNormal(100, 5)) AS k,count(*) AS c,bar(c, 0, 50000, 100)
FROM numbers(100000) GROUP BY k ORDER BY k ASC
除了正太分布,还有伯努利分布、二项分布、对数分布、指数分布、卡方分布、T分布、F分布、泊松分布等。
下面是指数分布的示例,用户消费记录符合指数分布:
CREATE TABLE purchases
(`dt` DateTime,`customer_id` UInt32,`total_spent` Float32
)
ENGINE = MergeTree
ORDER BY dt
INSERT INTO purchases SELECTnow() - randUniform(1, 1000000.),number,15 + round(randExponential(1 / 10), 2)
FROM numbers(1000000)
这里使用序号作为用户ID,采用均分分布随机数往前推移时间用于分散日期。消费金额采用指数分布,15是最低值。
最后进行验证:
SELECTfloor(total_spent) AS s,count(*) AS n,bar(n, 0, 350000, 50)
FROM purchases
GROUP BY s
ORDER BY s ASC
生成图示如下:
总结
本文介绍了生成随机测试的函数,包括基本语法及一些数据分布函数的应用,这些函数需至少22.10版本。利用这些函数让数据更真实、更贴近实际业务场景。参考资料:https://clickhouse.com/blog/generating-random-test-distribution-data-for-clickhouse
官方文档:https://clickhouse.com/docs/en/sql-reference/functions/random-functions#randuniform