Saltar al contenido principal
Generar datos aleatorios es útil para probar nuevos casos de uso o hacer benchmark de tu implementación. ClickHouse cuenta con una amplia variedad de funciones para generar datos aleatorios que, en muchos casos, evitan la necesidad de usar un generador de datos externo. Esta guía ofrece varios ejemplos de cómo generar conjuntos de datos aleatorios en ClickHouse con distintos requisitos de aleatoriedad.

Conjunto de datos simple con distribución uniforme

Caso de uso: Genera rápidamente un conjunto de datos de eventos de usuario con marcas de tiempo aleatorias y tipos de evento.
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: distribución uniforme de 10k usuarios
  • arrayElement(...): selecciona aleatoriamente uno de los tres tipos de eventos
  • Marcas de tiempo distribuidas a lo largo de las 24 horas anteriores

Distribución exponencial

Caso de uso: Simular importes de compra en los que la mayoría de los valores son bajos, pero unos pocos son elevados.
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);
  • Marcas de tiempo distribuidas uniformemente durante un período reciente
  • randExponential(1/10) — la mayoría de los valores cerca de 0, con un desplazamiento mínimo de 15 ([ClickHouse][1], [ClickHouse][2], [Atlantic.Net][3], [GitHub][4])

Eventos distribuidos temporalmente (Poisson)

Caso de uso: Simular la llegada de eventos que se agrupan en torno a un período específico (p. ej., la hora punta).
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);
  • Los eventos alcanzan su punto máximo alrededor del mediodía, con una desviación con distribución de Poisson

Distribución normal que varía con el tiempo

Caso de uso: Emular métricas del sistema (p. ej., uso de CPU) que varían con el tiempo.
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 sigue una onda sinusoidal diurna + variación aleatoria
  • Valores acotados a [0,100]

Datos categóricos y anidados

Caso de uso: Crear perfiles de usuario con varios intereses.
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);
  • Longitud aleatoria del array de 1 a 3
  • Tres puntuaciones por usuario para cada interés
Consulta el blog Generating Random Data in ClickHouse para ver más ejemplos.

Generación de tablas aleatorias

La función generateRandomStructure es especialmente útil cuando se combina con el generateRandom table engine para pruebas, benchmarking o la creación de datos ficticios con esquemas arbitrarios. Comencemos viendo cómo es una estructura aleatoria con la función generateRandomStructure:
SELECT generateRandomStructure(5);
Es posible que veas algo como esto:
c1 UInt32, c2 Array(String), c3 DateTime, c4 Nullable(Float64), c5 Map(String, Int16)
También puedes usar una semilla para obtener siempre la misma estructura:
SELECT generateRandomStructure(3, 42);
c1 String, c2 Array(Nullable(Int32)), c3 Tuple(UInt8, Date)
Ahora vamos a crear una tabla real y llenarla con datos aleatorios:
CREATE TABLE my_test_table
ENGINE = MergeTree
ORDER BY tuple()
AS SELECT * 
FROM generateRandom(
    'col1 UInt32, col2 String, col3 Float64, col4 DateTime',
    1,  -- semilla para la generación de datos
    10  -- número de valores aleatorios distintos
)
LIMIT 100;  -- 100 filas

-- Paso 2: Consultar la nueva tabla
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 │
└────────────┴───────────┴──────────────────────────┴─────────────────────┘
Combinemos ambas funciones para obtener una tabla completamente aleatoria. Primero, veamos la estructura que obtendremos:
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) │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ahora crea la tabla con esa estructura y usa la sentencia DESCRIBE para ver qué hemos creado:
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) │              │                    │         │                  │                │
   └──────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
Examina la primera fila para ver una muestra de los datos generados:
SELECT * FROM fully_random_table LIMIT 1 FORMAT vertical;
Row 1:
──────
c1: 80416293882.257732 -- 80,42 mil millones
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}
Última modificación el 10 de junio de 2026