> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentation de référence pour TABLE

# CREATE TABLE

Crée une nouvelle table. Par défaut, les tables sont créées uniquement sur le serveur actuel.
Les requêtes DDL distribuées utilisent la clause `ON CLUSTER`, qui est [décrite séparément](/fr/reference/statements/distributed-ddl).

<div id="syntax-forms">
  ## Formes de syntaxe
</div>

Cette requête peut prendre différentes formes de syntaxe selon le cas d'utilisation.

<div id="with-explicit-schema">
  ### Créer une table avec un schéma explicite
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr1] [COMMENT 'comment for column'] [compression_codec] [TTL expr1],
    name2 [type2] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr2] [COMMENT 'comment for column'] [compression_codec] [TTL expr2],
    ...
) ENGINE = engine
  [COMMENT 'comment for table']
```

Crée une table nommée `table_name` dans la base de données `db` ou dans la base de données courante si `db` n’est pas défini, avec la structure spécifiée entre crochets et le moteur `engine`.
La structure de la table est une liste de descriptions de colonnes, d’index secondaires, de projections et de contraintes. Si la [clé primaire](#primary-key) est prise en charge par le moteur, elle sera indiquée comme paramètre du moteur de table.

Dans le cas le plus simple, une description de colonne est de la forme `name type`. Exemple : `RegionID UInt32`.

Les modificateurs qui suivent le type — `COMMENT`, `compression_codec`, `STATISTICS`, `TTL`, `COLLATE`, `PRIMARY KEY` et `SETTINGS` par colonne — peuvent être écrits dans n’importe quel ordre, chacun au plus une fois. Par exemple, `RegionID UInt32 CODEC(ZSTD) COMMENT 'comment for column'` et `RegionID UInt32 COMMENT 'comment for column' CODEC(ZSTD)` sont identiques. Notez que `SHOW CREATE TABLE` normalise la déclaration de colonne : les modificateurs qui y restent sont toujours affichés dans l’ordre canonique `COMMENT`, `CODEC`, `STATISTICS`, `TTL`, `COLLATE`, `SETTINGS`, tandis qu’une `PRIMARY KEY` par colonne est déplacée hors de la déclaration de colonne vers la clause `PRIMARY KEY` au niveau de la table.

Des expressions peuvent également être définies pour les valeurs par défaut (voir ci-dessous).

Si nécessaire, la clé primaire peut être spécifiée, avec une ou plusieurs expressions de clé.

Des commentaires peuvent être ajoutés aux colonnes et à la table.

<div id="with-a-schema-similar-to-other-table">
  ### Créer une table avec le schéma d’une table existante
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db2.]table_clone AS [db.]table [ENGINE = engine]
```

ClickHouse permet de copier le schéma et les données d’une table existante.

Pour reproduire le schéma d’une table existante :

Cela crée une table avec la même structure qu’une autre table.

<div id="with-a-schema-and-data-cloned-from-another-table">
  ### Créer une table avec le schéma et les données d’une table existante
</div>

Pour répliquer le schéma et les données d'une table existante :

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db2.]table_clone CLONE AS [db.]table [ENGINE = engine]
```

Cette instruction crée une table avec le même schéma et les mêmes données qu’une table existante.  Une fois la nouvelle table créée, toutes les partitions de `db.table` lui sont attachées. En d’autres termes, les données de `db.table` sont clonées dans `db2.table_clone` lors de sa création. Cette requête est équivalente à ce qui suit :

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db2.]table_clone AS [db.]table [ENGINE = engine];
ALTER TABLE [db2.]table_clone ATTACH PARTITION ALL FROM [db.]table;
```

Pour ces deux fonctionnalités, vous pouvez spécifier un moteur différent pour la table. Si le moteur n'est pas spécifié, le même moteur que pour la table d'origine (`db.table`) sera utilisé.

<div id="from-a-table-function">
  ### Créer une table avec une fonction de table
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name AS table_function()
```

Crée une table produisant le même résultat que la [fonction de table](/fr/reference/functions/table-functions/index) spécifiée. La table créée fonctionnera également de la même manière que la fonction de table correspondante.

<div id="from-select-query">
  ### Créer une table avec une requête SELECT
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name[(name1 [type1], name2 [type2], ...)] ENGINE = engine AS SELECT ...
```

Crée une table dont la structure est similaire au résultat de la requête `SELECT`, avec le moteur `engine`, et la remplit avec les données issues de `SELECT`. Vous pouvez également spécifier explicitement la définition des colonnes.

Si la table existe déjà et que `IF NOT EXISTS` est spécifié, la requête n’aura aucun effet.

D’autres clauses peuvent apparaître après la clause `ENGINE` dans la requête. Consultez la documentation détaillée sur la création de tables dans les descriptions des [moteurs de table](/fr/reference/engines/table-engines/index).

**Exemple**

```sql title="Query" theme={null}
CREATE TABLE t1 (x String) ENGINE = Memory AS SELECT 1;
SELECT x, toTypeName(x) FROM t1;
```

```text title="Response" theme={null}
┌─x─┬─toTypeName(x)─┐
│ 1 │ String        │
└───┴───────────────┘
```

<div id="default_values">
  ## Spécifier les valeurs par défaut des colonnes
</div>

La description de colonne peut spécifier une expression de valeur par défaut sous la forme `DEFAULT expr`, `MATERIALIZED expr` ou `ALIAS expr`. Exemple : `URLDomain String DEFAULT domain(URL)`.

L’expression `expr` est facultative. Si elle est omise, le type de colonne doit être indiqué explicitement et la valeur par défaut sera `0` pour les colonnes numériques, `''` (la chaîne vide) pour les colonnes de type chaîne, `[]` (le tableau vide) pour les colonnes de type tableau, `1970-01-01` pour les colonnes de type date, ou `NULL` pour les colonnes Nullable.

Le type de colonne d’une colonne avec valeur par défaut peut être omis ; dans ce cas, il est déduit du type de `expr`. Par exemple, le type de la colonne `EventDate DEFAULT toDate(EventTime)` sera Date.

Si un type de données et une expression de valeur par défaut sont tous deux spécifiés, une fonction implicite de transtypage est insérée pour convertir l’expression dans le type spécifié. Exemple : `Hits UInt32 DEFAULT 0` est représenté en interne sous la forme `Hits UInt32 DEFAULT toUInt32(0)`.

Une expression de valeur par défaut `expr` peut faire référence à des colonnes de table quelconques et à des constantes. ClickHouse vérifie que les modifications de la structure de la table n’introduisent pas de boucles dans le calcul de l’expression. Pour INSERT, il vérifie que les expressions peuvent être résolues, c’est-à-dire que toutes les colonnes à partir desquelles elles peuvent être calculées ont bien été fournies.

<div id="default">
  ### DEFAULT
</div>

`DEFAULT expr`

Valeur par défaut standard. Si la valeur d’une telle colonne n’est pas spécifiée dans une requête INSERT, elle est calculée à partir de `expr`.

Exemple :

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    updated_at DateTime DEFAULT now(),
    updated_at_date Date DEFAULT toDate(updated_at)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test (id) VALUES (1);

SELECT * FROM test;
┌─id─┬──────────updated_at─┬─updated_at_date─┐
│  1 │ 2023-02-24 17:06:46 │      2023-02-24 │
└────┴─────────────────────┴─────────────────┘
```

<div id="materialized">
  ### MATERIALIZED
</div>

`MATERIALIZED expr`

Expression matérialisée. Les valeurs de ces colonnes sont automatiquement calculées d’après l’expression matérialisée spécifiée lors de l’insertion des lignes. Il n’est pas possible de spécifier explicitement des valeurs lors des `INSERT`.

De plus, les colonnes avec une valeur par défaut de ce type ne sont pas incluses dans le résultat de `SELECT *`. Cela permet de préserver l’invariant selon lequel le résultat d’un `SELECT *` peut toujours être réinséré dans la table à l’aide de `INSERT`. Ce comportement peut être désactivé avec le paramètre `asterisk_include_materialized_columns`.

Exemple :

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    updated_at DateTime MATERIALIZED now(),
    updated_at_date Date MATERIALIZED toDate(updated_at)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test VALUES (1);

SELECT * FROM test;
┌─id─┐
│  1 │
└────┘

SELECT id, updated_at, updated_at_date FROM test;
┌─id─┬──────────updated_at─┬─updated_at_date─┐
│  1 │ 2023-02-24 17:08:08 │      2023-02-24 │
└────┴─────────────────────┴─────────────────┘

SELECT * FROM test SETTINGS asterisk_include_materialized_columns=1;
┌─id─┬──────────updated_at─┬─updated_at_date─┐
│  1 │ 2023-02-24 17:08:08 │      2023-02-24 │
└────┴─────────────────────┴─────────────────┘
```

<div id="ephemeral">
  ### EPHEMERAL
</div>

`EPHEMERAL [expr]`

Colonne éphémère. Les colonnes de ce type ne sont pas stockées dans la table et il n'est pas possible d'effectuer un `SELECT` dessus. La seule utilité des colonnes éphémères est de servir à construire les expressions de valeur par défaut d'autres colonnes.

Un `INSERT` sans colonnes explicitement spécifiées ignorera les colonnes de ce type. Cela permet de préserver l'invariant selon lequel le résultat d'un `SELECT *` peut toujours être réinséré dans la table à l'aide de `INSERT`.

Exemple :

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    unhexed String EPHEMERAL,
    hexed FixedString(4) DEFAULT unhex(unhexed)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test (id, unhexed) VALUES (1, '5a90b714');

SELECT
    id,
    hexed,
    hex(hexed)
FROM test
FORMAT Vertical;

Row 1:
──────
id:         1
hexed:      Z��
hex(hexed): 5A90B714
```

<div id="alias">
  ### ALIAS
</div>

`ALIAS expr`

Colonnes calculées (synonyme). Les colonnes de ce type ne sont pas stockées dans la table et il n'est pas possible d'y INSERT des valeurs.

Lorsque des requêtes SELECT font explicitement référence à des colonnes de ce type, la valeur est calculée au moment de la requête à partir de `expr`. Par défaut, `SELECT *` exclut les colonnes ALIAS. Ce comportement peut être désactivé avec le paramètre `asterisk_include_alias_columns`.

Lorsque vous utilisez la requête ALTER pour ajouter de nouvelles colonnes, les anciennes données de ces colonnes ne sont pas écrites. À la place, lors de la lecture d'anciennes données qui n'ont pas de valeurs pour les nouvelles colonnes, les expressions sont calculées à la volée par défaut. Cependant, si l'évaluation des expressions nécessite d'autres colonnes qui ne sont pas indiquées dans la requête, ces colonnes seront également lues, mais uniquement pour les blocs de données qui en ont besoin.

Si vous ajoutez une nouvelle colonne à une table mais modifiez ensuite son expression par défaut, les valeurs utilisées pour les anciennes données changeront (pour les données dont les valeurs n'ont pas été stockées sur le disque). Notez que lors de l'exécution des fusions en arrière-plan, les données des colonnes absentes dans l'une des parties en cours de fusion sont écrites dans la partie fusionnée.

Il n'est pas possible de définir des valeurs par défaut pour les éléments des structures de données imbriquées.

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    size_bytes Int64,
    size String ALIAS formatReadableSize(size_bytes)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test VALUES (1, 4678899);

SELECT id, size_bytes, size FROM test;
┌─id─┬─size_bytes─┬─size─────┐
│  1 │    4678899 │ 4.46 MiB │
└────┴────────────┴──────────┘

SELECT * FROM test SETTINGS asterisk_include_alias_columns=1;
┌─id─┬─size_bytes─┬─size─────┐
│  1 │    4678899 │ 4.46 MiB │
└────┴────────────┴──────────┘
```

<div id="null-or-not-null-modifiers">
  ## Modificateurs `NULL` ou `NOT NULL`
</div>

Les modificateurs `NULL` et `NOT NULL` placés après le type de données dans une définition de colonne permettent ou non que celui-ci soit [Nullable](/fr/reference/data-types/nullable).

Si le type n’est pas `Nullable` et que `NULL` est spécifié, il sera traité comme `Nullable` ; si `NOT NULL` est spécifié, ce ne sera pas le cas. Par exemple, `INT NULL` équivaut à `Nullable(INT)`. Si le type est `Nullable` et que les modificateurs `NULL` ou `NOT NULL` sont spécifiés, une exception sera levée.

Voir aussi le paramètre [data\_type\_default\_nullable](/fr/reference/settings/session-settings/other#data_type_default_nullable).

<div id="primary-key">
  ## Clé primaire
</div>

Vous pouvez définir une [clé primaire](/fr/reference/engines/table-engines/mergetree-family/mergetree#primary-keys-and-indexes-in-queries) lors de la création d'une table. La clé primaire peut être définie de deux façons :

<Columns cols={2}>
  <div>
    **Dans la liste des colonnes**

    ```sql theme={null}
    CREATE TABLE [db.]table_name
    (
        name1 type1, name2 type2, ...,
        PRIMARY KEY(expr1[, expr2,...])
    )
    ENGINE = engine;
    ```
  </div>

  <div>
    **Hors de la liste des colonnes**

    ```sql theme={null}
    CREATE TABLE [db.]table_name
    (
        name1 type1, name2 type2, ...
    )
    ENGINE = engine
    PRIMARY KEY(expr1[, expr2,...]);
    ```
  </div>
</Columns>

<Tip>
  Vous ne pouvez pas combiner ces deux méthodes dans une seule requête.
</Tip>

<div id="constraints">
  ## Spécifier les contraintes de table
</div>

En plus de la description des colonnes, des contraintes peuvent être définies :

<div id="constraint">
  ### CONSTRAINT
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1],
    ...
    CONSTRAINT constraint_name_1 CHECK boolean_expr_1,
    ...
) ENGINE = engine
```

`boolean_expr_1` peut être n’importe quelle expression booléenne. Si des contraintes sont définies pour la table, chacune d’elles sera vérifiée pour chaque ligne de la requête `INSERT`. Si une contrainte n’est pas respectée, le serveur renverra une exception indiquant le nom de la contrainte et l’expression vérifiée.

L’ajout d’un grand nombre de contraintes peut nuire aux performances des requêtes `INSERT` volumineuses.

Les contraintes existantes dans toutes les tables peuvent être consultées dans la table [`system.constraints`](/fr/reference/system-tables/constraints).

<div id="assume">
  ### ASSUME
</div>

La clause `ASSUME` est utilisée pour définir une `CONSTRAINT` sur une table, supposée être vraie. Cette contrainte peut ensuite être utilisée par l'optimiseur pour améliorer les performances des requêtes SQL.

Prenez cet exemple où `ASSUME CONSTRAINT` est utilisé lors de la création de la table `users_a` :

```sql theme={null}
CREATE TABLE users_a (
    uid Int16, 
    name String, 
    age Int16, 
    name_len UInt8 MATERIALIZED length(name), 
    CONSTRAINT c1 ASSUME length(name) = name_len
) 
ENGINE=MergeTree 
ORDER BY (name_len, name);
```

Ici, `ASSUME CONSTRAINT` sert à indiquer que la fonction `length(name)` est toujours égale à la valeur de la colonne `name_len`. Cela signifie que chaque fois que `length(name)` est appelée dans une requête, ClickHouse peut la remplacer par `name_len`, ce qui devrait être plus rapide, car cela évite d’appeler la fonction `length()`.

Ensuite, lors de l’exécution de la requête `SELECT name FROM users_a WHERE length(name) < 5;`, ClickHouse peut l’optimiser en `SELECT name FROM users_a WHERE name_len < 5`; grâce à `ASSUME CONSTRAINT`. La requête peut ainsi s’exécuter plus rapidement, car il n’est plus nécessaire de calculer la longueur de `name` pour chaque ligne.

`ASSUME CONSTRAINT` **ne fait pas respecter la contrainte** ; il informe simplement l’optimiseur que la contrainte est supposée vraie. Si la contrainte n’est pas réellement vraie, les résultats des requêtes peuvent être incorrects. Par conséquent, vous ne devez utiliser `ASSUME CONSTRAINT` que si vous êtes sûr que la contrainte est vraie.

<div id="ttl-expression">
  ## Définir la durée de conservation avec TTL
</div>

Définit la durée de conservation des valeurs. Ne peut être spécifiée que pour les tables de la famille MergeTree. Pour une description détaillée, consultez [TTL pour les colonnes et les tables](/fr/reference/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-ttl).

<div id="column_compression_codec">
  ## Sélectionner les codecs de compression des colonnes
</div>

<a id="general-purpose-codecs" />

<a id="none" />

<a id="lz4" />

<a id="lz4hc" />

<a id="zstd" />

<a id="zxc" />

<a id="zstd_qat" />

<a id="deflate_qpl" />

<a id="specialized-codecs" />

<a id="delta" />

<a id="doubledelta" />

<a id="gcd" />

<a id="gorilla" />

<a id="alp" />

<a id="fpc" />

<a id="sz3" />

<a id="t64" />

<a id="quantized" />

<a id="encryption-codecs" />

<a id="aes_128_gcm_siv" />

<a id="aes-256-gcm-siv" />

<a id="adaptive-codec-selection" />

Par défaut, ClickHouse utilise la compression `lz4` dans la version autogérée et `zstd` dans ClickHouse Cloud. Vous pouvez également définir la méthode de compression pour chaque colonne dans la requête `CREATE TABLE` :

```sql theme={null}
CREATE TABLE codec_example
(
    dt Date CODEC(ZSTD),
    ts DateTime CODEC(LZ4HC),
    float_value Float32 CODEC(NONE),
    double_value Float64 CODEC(LZ4HC(9)),
    value Float32 CODEC(Delta, ZSTD)
)
ENGINE = <Engine>
...
```

Pour découvrir les codecs de compression à usage général, spécialisés et de chiffrement disponibles, consultez [Codecs de compression des colonnes](/fr/reference/statements/create/table/codec).

<div id="temporary-tables">
  ## Créer des tables temporaires
</div>

ClickHouse prend en charge les tables temporaires, qui disparaissent à la fin de la session. Pour en savoir plus, consultez [CREATE TEMPORARY TABLE](/fr/reference/statements/create/table/temporary-table).

<div id="replace-table">
  ## Mettre à jour une table de façon atomique avec REPLACE TABLE
</div>

<a id="syntax" />

<a id="examples" />

L’instruction `REPLACE` vous permet de mettre à jour une table [de façon atomique](/fr/concepts/core-concepts/glossary#atomicity). Pour plus de détails, consultez [REPLACE TABLE](/fr/reference/statements/create/table/replace-table).

<div id="comment-clause">
  ## Ajouter un commentaire à une table
</div>

Vous pouvez ajouter un commentaire à une table lors de sa création.

**Syntaxe**

```sql theme={null}
CREATE TABLE [db.]table_name
(
    name1 type1, name2 type2, ...
)
ENGINE = engine
COMMENT 'Comment'
```

<Note>
  La clause `COMMENT` doit être spécifiée **après** toute clause propre au stockage, telle que `PARTITION BY`, `ORDER BY` et les `SETTINGS` propres au stockage.

  Après la clause `COMMENT`, seuls les `SETTINGS` propres aux requêtes (comme `max_threads`, etc.) seront analysés, et non les paramètres liés au stockage.

  Cela signifie que l’ordre correct des clauses est le suivant :

  * `ENGINE`
  * clauses de stockage
  * `COMMENT`
  * paramètres de requête (le cas échéant)
</Note>

**Exemple**

```sql title="Query" theme={null}
CREATE TABLE t1 (x String) ENGINE = Memory COMMENT 'The temporary table';
SELECT name, comment FROM system.tables WHERE name = 't1';
```

```text title="Response" theme={null}
┌─name─┬─comment─────────────┐
│ t1   │ The temporary table │
└──────┴─────────────────────┘
```

<div id="related-content">
  ## Contenu connexe
</div>

* Blog : [Optimiser ClickHouse grâce aux schémas et aux codecs](https://clickhouse.com/blog/optimize-clickhouse-codecs-compression-schema)
* Blog : [Travailler avec des données de séries temporelles dans ClickHouse](https://clickhouse.com/blog/working-with-time-series-data-and-functions-ClickHouse)
