Create a UDT

User-Defined Types (UDTs) can be used to store multiple data fields, each with a name and type, on one column. The fields in a UDT can be any valid data type, including collections and other UDTs.

To use a UDT, you must create the UDT itself, which is effectively a custom data type definition. After a UDT is created, you can use it to define a table column, like any other data type, with CREATE TABLE or ALTER TABLE. A UDT can be used in multiple tables, like any other data type.

UDTs are stored per keyspace. However, you can access a UDT defined on one keyspace from another keyspace by using the <keyspace_name>.<type_name> notation.

Use a CREATE TYPE statement to create a user-defined type named basic_info:

CREATE TYPE IF NOT EXISTS cycling.basic_info ( 
  birthday timestamp, 
  nationality text, 
  height text,
  weight text
);
DESCRIBE TYPE cycling.basic_info;
Results
CREATE TYPE cycling.basic_info (
    birthday timestamp,
    nationality text,
    height text,
    weight text
);

Create a table for storing cyclist data in columns of type basic_info. Use the frozen keyword in the definition of the user-defined type column.

The frozen keyword is not required for UDTs that contain only non-collection fields.

When using the frozen keyword, you cannot update parts of a user-defined type value. The entire value must be overwritten. The database treats the value of a frozen, user-defined type like a blob.

CREATE TABLE IF NOT EXISTS cycling.cyclist_stats ( 
  id UUID PRIMARY KEY,
  lastname text,
  basics basic_info
);

A user-defined type can be nested in another column type. The example below nests a UDT in a frozen list named races.

CREATE TYPE IF NOT EXISTS cycling.race (
  race_title text,
  race_date timestamp,
  race_time text
);
DESCRIBE TYPE cycling.race;
Results
CREATE TYPE cycling.race (
    race_title text,
    race_date timestamp,
    race_time text
);
CREATE TABLE IF NOT EXISTS cycling.cyclist_races (
  id UUID PRIMARY KEY,
  lastname text,
  firstname text,
  races list<FROZEN <race>>
);
Results
CREATE TABLE cycling.cyclist_races (
    id uuid PRIMARY KEY,
    firstname text,
    lastname text,
    races list<frozen<race>>
) WITH additional_write_policy = '99PERCENTILE'
    AND bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND crc_check_chance = 1.0
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND nodesync = {'enabled': 'true', 'incremental': 'true'}
    AND read_repair = 'BLOCKING'
    AND speculative_retry = '99PERCENTILE';

Was this helpful?

Give Feedback

How can we improve the documentation?

© 2025 DataStax, an IBM Company | Privacy policy | Terms of use | Manage Privacy Choices

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries. Kubernetes is the registered trademark of the Linux Foundation.

General Inquiries: +1 (650) 389-6000, info@datastax.com