Passer au contenu principal
La génération de données aléatoires est utile pour tester de nouveaux cas d’usage ou évaluer les performances de votre implémentation. ClickHouse propose un large éventail de fonctions pour générer des données aléatoires qui, dans de nombreux cas, évitent d’avoir recours à un générateur de données externe. Ce guide présente plusieurs exemples de génération de jeux de données aléatoires dans ClickHouse, selon différents besoins en matière d’aléa.

Jeu de données simple à distribution uniforme

Cas d’usage : générez rapidement un jeu de données d’événements utilisateur avec des horodatages aléatoires et différents types d’événements.
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 : distribution uniforme de 10 000 utilisateurs
  • arrayElement(...) : sélectionne aléatoirement l’un des trois types d’événements
  • Horodatages répartis sur les 24 heures précédentes

Distribution exponentielle

Cas d’usage : simuler des montants d’achat dont la plupart des valeurs sont faibles, mais dont quelques-unes sont élevées.
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);
  • Horodatages uniformément répartis sur une période récente
  • randExponential(1/10) — la plupart des totaux sont proches de 0, avec un minimum fixé à 15 ([ClickHouse][1], [ClickHouse][2], [Atlantic.Net][3], [GitHub][4])

Événements répartis dans le temps (Poisson)

Cas d’usage : simuler des arrivées d’événements qui se concentrent autour d’un créneau précis (par ex. l’heure de pointe).
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);
  • Les événements culminent vers midi, avec une variation suivant une loi de Poisson

Distribution normale variant dans le temps

Cas d’usage : Simulez des métriques système (p. ex., l’utilisation du CPU) qui varient au fil du temps.
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 suit une onde sinusoïdale diurne + une composante aléatoire
  • Valeurs bornées à [0,100]

Données catégorielles et imbriquées

Cas d’usage : Créez des profils d’utilisateurs avec des centres d’intérêt multiples.
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);
  • Longueur de tableau aléatoire comprise entre 1 et 3
  • Trois scores par utilisateur pour chaque centre d’intérêt
Consultez l’article de blog Generating Random Data in ClickHouse pour encore plus d’exemples.

Génération de tables aléatoires

La fonction generateRandomStructure est particulièrement utile lorsqu’elle est associée au moteur de table generateRandom pour les tests, le benchmarking ou la création de données fictives avec des schémas arbitraires. Commençons simplement par voir à quoi ressemble une structure aléatoire à l’aide de la fonction generateRandomStructure :
SELECT generateRandomStructure(5);
Vous pourriez voir quelque chose comme ceci :
c1 UInt32, c2 Array(String), c3 DateTime, c4 Nullable(Float64), c5 Map(String, Int16)
Vous pouvez également utiliser une graine pour obtenir la même structure à chaque fois :
SELECT generateRandomStructure(3, 42);
c1 String, c2 Array(Nullable(Int32)), c3 Tuple(UInt8, Date)
Créons maintenant une véritable table et remplissons-la avec des données aléatoires :
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 │
└────────────┴───────────┴──────────────────────────┴─────────────────────┘
Combinons les deux fonctions pour obtenir une table complètement aléatoire. Voyons d’abord quelle structure nous allons obtenir :
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) │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Créez maintenant la table avec cette structure, puis utilisez l’instruction DESCRIBE pour voir ce que nous avons créé :
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) │              │                    │         │                  │                │
   └──────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
Examinez la première ligne pour voir un aperçu des données générées :
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}
Dernière modification le 29 juin 2026