New ACM paper, free-tier cloud, and open-source license

Meet TypeDB and TypeQL

TypeDB is a polymorphic database with a conceptual data model, a strong subtyping system, a symbolic reasoning engine, and a beautiful and elegant type-theoretic language: TypeQL.

Visit learning center Read philosophy

Conceptual Modeling

Entity-Relation-Attribute

TypeQL implements the Enhanced Entity-Relation-Attribute model for its schemas and data. Entities, relations, and attributes are all first-class citizens and subtypable, allowing for expressive modeling without normalization or reification.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define

id sub attribute, value string;
email sub id;
path sub id;
name sub id;

user sub entity,
    owns email @unique,
    plays permission:subject,
    plays request:requestee;
file sub entity,
    owns path,
    plays permission:object;
action sub entity,
    owns name,
    plays permission:action;

permission sub relation,
    relates subject,
    relates object,
    relates action,
    plays request:target;
request sub relation,
    relates target,
    relates requester;

Declarative Schema

The schema provides a structural blueprint for data organization, ensuring referential integrity in production. Extend your data model seamlessly in TypeDB, maintaining integrity during model updates and avoiding any query rewrites or code refactors.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define

full-name sub attribute, value string;
id sub attribute, value string;
email sub id;
employee-id sub id;

user sub entity,
    owns full-name,
    owns email @unique;
employee sub user,
    owns employee-id @key;

Abstract Types

Define abstract entity, relation, and attribute types in your schema to extend concrete types from. Build templates with ownership of abstract attributes and playing of abstract roles for subtypes to extend and override.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define

id sub attribute, abstract, value string;
email sub id;
path sub id;

user sub entity, abstract,
    owns id;
employee sub user,
    owns email as id;
resource sub entity, abstract,
    owns id,
    plays collection-membership:member;
file sub resource,
    owns path as id;

membership sub relation, abstract,
    relates parent,
    relates member;
team-membership sub membership,
    relates team as parent;
collection-membership sub membership,
    relates collection as parent;

Type Inheritance

Type inheritance in TypeDB allows you to create new types based on existing ones, providing hierarchy and abstraction in your data model. By inheriting attributes and relationships from parent types, schema design is simplified, promoting reusability and consistency.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define

user sub entity,
    owns full-name,
    owns email;
intern sub user;
employee sub user,
    owns employee-id,
    owns title;
part-time-employee sub employee,
    owns weekly-hours;

Strong Type System

Type Inference

TypeDB’s type inference resolves queries against the schema to generate polymorphic results. Queries on supertypes automatically return results for subtypes, and the types of variables can even be omitted to match only the shape of the data.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define
user sub entity, abstract, owns id, plays resource-ownership:owner;
employee sub user, owns employee-id as id;
resource sub entity, abstract, owns id, plays resource-ownership:resource;
file sub resource, owns path as id;
database sub resource, owns name as id;
commit sub resource, owns hash as id;
resource-ownership sub relation, relates resource, relates owner;

match
$user has id $user-id;
$rsrc has id $rsrc-id;
($user, $rsrc) isa $relation-type;
get; 

Semantic Validation

TypeDB validates all queries and rules against the type system defined in the schema to ensure semantic correctness. Nonsensical writes are automatically blocked, and nonsensical reads throw an exception instead of returning an empty result set.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define
weekly-hours sub attribute value long;
full-time-employee sub employee;
part-time-employee sub employee, owns weekly-hours;

insert $francois isa full-time-employee,
    has full-name "François Durand",
    has email "francois@vaticle.com",
    has employee-id 184,
    has weekly-hours 35;

# [THW03] Invalid Write: Attribute of type 'weekly-hours' is
# not defined to be owned by type 'full-time-employee'.

Symbolic Reasoning

Rule-Based Reasoning

TypeDB’s symbolic reasoning enables the automated deduction of new facts and relationships based on existing data and rules you define. Rule chaining and branching allow complex behavior to arise from simple rules, creating rich, high-level insights.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define

rule transitive-team-membership: when {
    (team: $team-1, member: $team-2) isa team-membership;
    (team: $team-2, member: $member) isa team-membership;
} then {
    (team: $team-1, member: $member) isa team-membership;
};

rule inherited-team-permission: when {
    (team: $team, member: $member) isa team-membership;
    (subject: $team, object: $obj, action: $act) isa permission;
} then {
    (subject: $member, object: $obj, action: $act) isa inherited-permission;
};

Explanations

TypeDB's reasoning engine functions on deductive reasoning, so inferred data can always be traced back to its source. Perform root-cause analysis using TypeDB’s Explanations feature, guaranteeing accountability of generated data.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

query = "match $perm isa inherited-permission; get;"

with open_session.transaction(TransactionType.READ) as tx:
    results = tx.query().get(query)
    for result in results:
        inherited_permission = result.explainables().relation("perm")
        explanations = tx.query().explain(inherited_permission)
        for explanation in explanations:
            condition = explanation.condition()
            rule = explanation.rule()
            conclusion = explanation.conclusion()

Polymorphic Queries

Variablized Types

Schema types and relation roles can be variablized in addition to data instances, making schema querying as easy as data querying. Queries can contain both schema and data constraints, allowing for patterns that represent highly complex conceptual structures.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define
user sub entity, has full-name;
    plays mentorship:mentor,
    plays mentorship:trainee;
employee sub user;
contractor sub user;
mentorship sub relation,
    relates mentor,
    relates trainee;

match
$user isa $user-type, has full-name;
$user-type sub user;
($role-1: $user, $role-2: $other-user) isa mentorship;
mentorship relates $role-1, relates $role-2;
get; 

Inheritance Polymorphism

TypeQL implements inheritance polymorphism, allowing subtypes to inherit the behaviors of the supertypes they extend, whether concrete or abstract. Write TypeQL queries that return results with a common supertype, without enumerating the subtypes.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define
user sub entity,
    owns full-name,
    owns email @unique;
employee sub user,
    owns employee-id @key;

insert
$john isa employee,
    has full-name "John Doe",
    has email "john@vaticle.com",
    has employee-id 183;

Interface Polymorphism

Ensure conceptual consistency between defined types and their behaviors in perfect parallel to your object model by harnessing TypeQL’s interface polymorphism. Types can own the same attributes and play the same roles, even if they share no common supertypes.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define
name sub attribute, value string;
user sub entity, owns name;
team sub entity, owns name;
table sub entity, owns name;

match $x has name; get;

Parametric Polymorphism

Write queries that create or delete data instances without specifying their types by utilizing parametric polymorphism. Queries are resolved against the schema when run, allowing them to write data of multiple types matching declared properties.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match
$data isa $T;
$data has data-expiration-date < 2023-09-27;
delete
$data isa $T;

Modern Language

Near Natural

Due to its OOP properties and simple syntax, queries written in TypeQL read close to natural language. Domain experts and non-technical users alike can quickly grasp the intent of a query, reducing the learning curve and making query maintenance a breeze.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match $kevin isa user, has email "kevin@vaticle.com";
insert
$chloe isa full-time-employee,
    has full-name "Chloé Dupond",
    has email "chloe@vaticle.com",
    has employee-id 185,
    has weekly-hours 35;
$hire (employee: $chloe, ceo: $kevin) isa hiring,
    has date 2023-09-27;

Fully Declarative

TypeQL is fully declarative, allowing you to define query patterns without considering execution strategy. TypeDB’s query planner always deconstructs queries into the most optimized plans, so you never have to think about the logical implementation.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define
user sub entity,
    owns full-name,
    owns email;
intern sub user;
employee sub user,
    owns employee-id;
full-time-employee sub employee;
part-time-employee sub employee,
    owns weekly-hour;
contractor sub user,
    owns contract-number;

match
$user isa $user-type;
$user-type sub user;
fetch
$user: attribute;
$user-type;

Composable Patterns

Patterns in TypeQL are fully composable. Every complex pattern can be broken down into a conjunction of atomic constraints, which can be concatenated in any order. Any pattern composed of valid constraints is guaranteed to be valid itself, no matter how complex.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match $user isa user; get; 

match
$user isa user;
$user has email "john@vaticle.com";
get; 

match
$user isa user;
$user has email "john@vaticle.com";
(team: $team, member: $user) isa team-membership;
get;

match
$user isa user;
$user has email "john@vaticle.com";
(team: $team, member: $user) isa team-membership;
$team has name "Engineering";
get; 

Nested Subqueries

Search for complex data structures with a single query and network trip using nested subqueries. Retrieve results for nested queries as a list or perform aggregations over them, including results for optional attribute matches.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match $user is user;
fetch
$user: email, full-name, employee-id;
teams: {
    match
    (team: $team, member: $user) isa team-membership;
    fetch
    $team: name;
};
permission-count: {
    match
    $perm (subject: $user) isa permission;
    get; count;
};

Structured Results

Query results can be serialized for easy consumption in your application with TypeQL’s native JSON outputs. Switch from an asynchronous answer stream to a single structured collection, and define the result format using projections in the query structure.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match $user isa full-time-employee;
fetch $user as employee: attribute;
limit 1;

# JSON output:
[{
    "employee": {
        "type": { "root": "entity", "label": "full-time-employee" },
	"attribute": [
            { "value": "Chloé Dupond", "value_type": "string", "type": { "root": "attribute", "label": "full-name" } },
            { "value": "chloe@vaticle.com", "value_type": "string", "type": { "root": "attribute", "label": "email" } },
            { "value": 185, "value_type": "long", "type": { "root": "attribute", "label": "employee-id" } },
            { "value": 35, "value_type": "long", "type": { "root": "attribute", "label": "weekly-hours" } }
        ]
    }
}]

Aggregates and Expressions

Perform basic mathematical operations directly in your queries or rules with aggregations and arithmetic expressions, enabling dynamic and efficient data computation.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match
$user is user;
$perm (subject: $user) isa permission;
group $user;
get; count;

match
$dir isa directory,
    has path $path,
    has size $kb;
?gb = $kb / 1024 ^ 2;
get $path, ?gb;

Query Builder

Use the TypeQL query builder to auto-generate queries using a code-first approach in Java or Rust, with other languages coming soon. This permits the generation of TypeDB queries through a robust and streamlined process.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

TypeQLMatch.Filtered builtQuery = TypeQL.match(
    cVar("user").isa("user").has("full-name", "Kevin Morrison"),
    cVar("file").isa("file").has("path", cVar("path")),
    cVar("perm").rel(cVar("user")).rel(cVar("file")).isa("permission")
).get(cVar("path"));

// builtQuery =
// match $user isa user, has full-name 'Kevin Morrison'; 
// $file isa file, has path $path;
// $perm ($user, $file) isa permission;
// get $path;

Query Templates

Build query templates that accept a tuple of attribute values as parameters and execute them repeatedly for lists of supplied values. The template is stored in the transaction cache, reducing network load and ensuring sanitization of input strings.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match
$fake-example isa fakefake;
$fake-example has fake-name "Faki Fake Fakee";
$fake-example has fake-age 4242;

insert
$super-fake isa fakish, 
    has fake-name "Fakoon",
    has fake-status "Fakake",
    has fake-job "Faker at FakeCorp";
$f (faker: $super-fake, fakee: $fakefake) isa faker-fakee;

Expressive Relations

N-ary Relations

Construct rich data representations by directly implementing unary, binary, ternary, and n-ary relations in your conceptual model. TypeQL’s expressivity allows you to use the same constructor format for all relations, regardless of the number of roleplayers.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match
$omar isa contractor, has email "omar@vaticle.com";
insert 
$term (user: $omar) isa user-termination,
    has termination-date 2023-09-19,
    has termination-reason "end of contract";

match
$naomi isa user, has email "naomi@vaticle.com";
$eng isa group, has name "Engineering";
insert
$own (group: $eng, owner: $naomi) isa group-ownership;

match
$john isa user, has email "john@vaticle.com";
$readme isa file, has path "/usr/johndoe/repos/typedb/readme.md";
$edit isa action, has name "edit file";
insert
$perm (subject: $john, object: $readme, action: $edit) isa permission;

Nested Relations

Relations are first-class citizens in TypeQL and so can own attributes and play roles in other relations just like entities. With no limit to the depth of nesting for relations, you can express the full richness of your data without reifying your data model.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match
$john isa user, has email "john@vaticle.com";
$readme isa file, has path "/usr/johndoe/repos/typedb/readme.md";
$edit isa action, has name "edit file";
$perm (subject: $john, object: $readme, action: $edit) isa permission;
$kevin isa user, has email "kevin@vaticle.com";
insert
$rqst (target: $perm, requestee: $kevin) isa change-request,
    has requested-change "revoke";

Variadic Relations

With TypeQL’s expressive relation constructor, you can easily implement relations where the same roleplayer plays multiple roles, multiple roleplayers play the same role, or a combination of both. Read queries always return all matched roleplayers.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match
$submit isa action, has name "submit order";
$approve isa action, has name "approve order";
insert
(segregated-action: $submit, segregated-action: $approve) isa segregation-policy;

match
$kevin isa user, has email "kevin@vaticle.com";
insert
(reviewer: $kevin, reviewee: $kevin) isa permission-review;

Cardinality Constraints

All attributes and relations have many-to-many cardinality by default. Apply constraints in the schema to apply stricter cardinalities wherever needed, with the expressivity to select a single value or a specific range.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define

name sub attribute, value string;
object-type sub attribute, value string;

action sub entity,
    owns name @card(1),
    owns object-type @card(1,*)
    plays segregation-policy:segregated-action @card(0,*);

segregation-policy sub relation,
    relates segregated-action @card(2);

Intuitive Attributes

Multi-Valued Attributes

TypeQL is a conceptual data modeling language, and all attributes have many-to-many cardinality by default. Giving an entity or relation multiple attributes of the same type is as simple as declaring them in an insert, and read queries automatically return all values.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

insert $john isa full-time-employee,
    has primary-email "john.doe@vaticle.com",
    has email "j.doe@vaticle.com",
    has email "john@vaticle.com",
    has email "sales@vaticle.com";

Globally Unique Attributes

Attributes are globally unique in TypeQL. If two entities each have an attribute with the same type and value, then they both have the same attribute instance. This allows for highly efficient data traversals, keeps disk usage low, and maintains a consistent model.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

insert
$roadmap isa file,
    has path "/vaticle/feature-roadmap.pdf",
    has confidentiality "public";
$cloud isa repository,
    has name "typedb-cloud",
    has confidentiality "restricted";
$sales isa database,
    has name "sales",
    has confidentiality "restricted";

match $rsrc has confidentiality $conf;
fetch $conf;

No Nulls

Unlike SQL and NoSQL modeling languages, TypeQL is entirely conceptual and does not need to implement nulls to store the absence of a value. Keep nulls out of your query results without compromising for a schema-less database.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

insert
$john isa user, has full-name "John Doe";
$david isa user, has email "david@vaticle.com";

match $user isa user;
fetch $user: full-name, email;

# JSON output:
[{
    "user": {
        "type": { "root": "entity", "label": "user" },
        "full-name": [
            { "value": "John Doe", "value_type": "string", "type": { "root": "attribute", "label": "full-name" } }
        ],
        "email": []
    }
}, {
    "user": {
        "type": { "root": "entity", "label": "user" },
        "full-name": [],
        "email": [
            { "value": "david@vaticle.com", "value_type": "string", "type": { "root": "attribute", "label": "email" } }
        ]
    }
}]

Attribute Constraints

Define a key constraint on an attribute to make ownership of that attribute required and ensure a unique value. Alternatively, use a unique constraint instead to ensure uniqueness without requiring ownership. Apply regex constraints to string attributes to enforce defined patterns.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

define
full-name sub attribute, value string;
office-location sub attribute, value string;
id sub attribute, value string;
email sub id;
employee-id sub id;
user sub entity,
    owns full-name,
    owns email @unique, regex "^(.+)@(\\S+)$";
employee sub user,
    owns employee-id @key,
    owns office-location, regex "^(London|Paris|Dublin)$";

Purely Abstract Attributes

Define abstract attribute types with no declared value type, and extend them to define subtypes with different value types. Easily retrieve attribute values of different types by querying the abstract supertype.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35

define
id sub attribute, abstract;
email sub id, value string;
employee-id sub id, value long;
path sub id, value string;
user sub entity, owns email;
employee sub user, owns employee-id;
resource sub entity, abstract, owns id;
file sub resource, owns path as id;

match
$ent isa entity;
fetch
$ent: id;

[{
    "ent": {
        "type": { "root": "entity", "label": "employee" },
        "id": [
            { "value": "francois@vaticle.com", "value_type": "string", "type": { "root": "attribute", "label": "email" } },
            { "value": 184, "value_type": "long", "type": { "root": "attribute", "label": "employee-id" } }
        ]
    }
},{
    "ent": {
        "type": { "root": "entity", "label": "file" },
        "id": [
            { "value": "/vaticle/upcoming-features.pdf", "value_type": "string", "type": { "root": "attribute", "label": "path" } }
        ]
    }
}]

Compound Value Types

Define compound value types for your attributes constructed from primitive types.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

match
$fake-example isa fakefake;
$fake-example has fake-name "Faki Fake Fakee";
$fake-example has fake-age 4242;

insert
$super-fake isa fakish, 
    has fake-name "Fakoon",
    has fake-status "Fakake",
    has fake-job "Faker at FakeCorp";
$f (faker: $super-fake, fakee: $fakefake) isa faker-fakee;

Native Language Drivers

cargo add typedb-driver
pip install typedb-driver
npm install typedb-driver
com.vaticle.typedb:typedb-driver
dotnet add package TypeDB.Driver
#include <typedb.hpp>
#include <typedb_driver.h>

Go

go get github.com/vaticle/typedb-driver/go

Request your language

Robust API

ACID Compliance

TypeDB is ideal for complex and highly transactional applications due to its ACID compliance, ensuring data integrity and reliability. This prevents corruption and guarantees consistency during concurrent transactions.

Asynchronous Protocol

Communication with TypeDB servers is fully asynchronous, preventing any bottlenecks due to query processing. Send queries concurrently from the client, taking only as long as the network round-trip, while the server continues to process the received queries concurrently.

Reactive Streaming

TypeDB servers return query results in a stream as they are discovered. This enables the application to consume the results lazily for built-in vertical parallelism. Answer streaming is reactive, allowing the server to optimize for the rate of consumption and network latency.

Stateful & Programmatic

TypeDB’s network API streamlines integration with the database with fine control over connections, sessions, and transactions. Maximize performance based on your use case with automatic cache optimization, from high-speed bulk loading to high-volume reads.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

let connection = Connection::new_core("localhost:1729")?;
let databases = DatabaseManager::new(connection);

databases.create("access-management-db").await?;

let session = Session::new(databases.get("access-management-db").await?, SessionType::Schema).await?;
let tx = session.transaction(TransactionType::Write).await?;
tx.query().define(access_management_schema).await?;
tx.commit().await?;
drop(session);

let session = Arc::new(Session::new(databases.get("access-management-db").await?, SessionType::Data).await?);
futures::future::try_join_all(access_management_data_batches.into_iter().map(|batch| {
    let session = session.clone();
    async move {
        let tx = session.transaction(TransactionType::Write).await?;
        batch.iter().try_for_each(|query| tx.query().insert(query).map(|_| ()))?;
        tx.commit().await
    }
})).await?;

let tx = session.transaction(TransactionType::Read).await?;
let mut stream = tx.query().get("match $u isa user; get;")?;

Programmatic Schema Migration

Transactional Mutations

Execute complex schema mutations with ACID guarantees by using TypeDB’s stateful API. Mutations are executed via schema-write transactions, ensuring large-scale migrations can be carried out in production without inconsistent states or downtime.

Existing Data Validation

All schema mutation operations can be performed with data in place. By utilizing transactions, existing data can enter illegal states within the scope of the transaction, as long as they are resolved by commit. Any remaining inconsistencies will trigger a rollback.

Type Hierarchy Modification

The type hierarchies declared in the schema are entirely mutable. New types can be defined, existing types can be undefined, and the supertype of any type can be changed to any other type, with inherited behaviors automatically re-assigned where necessary.

Type Behavior Modification

Modify the behaviors of types with complete flexibility. Rename types, assign or de-assign ownership of attributes, create or remove roles from relations, and add or remove the ability for types to play roles, with new behaviors automatically inherited in hierarchies.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33

let connection = Connection::new_core("localhost:1729")?;
let databases = DatabaseManager::new(connection);
let session = Session::new(databases.get("access-management-db").await?, SessionType::Schema).await?;
let tx = session.transaction(TransactionType::Write).await?;

// create a new abstract type "user"
let mut user = tx.concept().put_entity_type("user".to_owned()).await?;
user.set_abstract(&tx).await?;

// change the supertype of "employee" to "user"
let mut employee = tx.concept().get_entity_type("employee".to_owned()).await?.unwrap();
employee.set_supertype(&tx, user.clone()).await?;

// change the supertype of "contractor" to "user"
let mut contractor = tx.concept().get_entity_type("contractor".to_owned()).await?.unwrap();
contractor.set_supertype(&tx, user.clone()).await?;

// move "email" and "name" attribute types to be owned by "user" instead of "employee"
let email = tx.concept().get_attribute_type("email".to_owned()).await?.unwrap();
let mut name = tx.concept().get_attribute_type("name".to_owned()).await?.unwrap();
employee.unset_owns(&tx, email.clone()).await?;
employee.unset_owns(&tx, name.clone()).await?;
user.set_owns(&tx, email, None, Vec::new()).await?;
user.set_owns(&tx, name.clone(), None, Vec::new()).await?;

// rename "name" attribute type to "full-name"
name.set_label(&tx, "full-name".to_owned()).await?;

// commit all schema changes in one transaction, which will fail if we violate any data validation
tx.commit().await?;

Beautiful IDE

Dedicated Environment

TypeDB Studio is a cross-platform IDE for developing with TypeDB that offers a consistent experience across Windows, macOS, and Linux operating systems. Manage databases, build and execute queries, and explore results with an integrated experience.

Schema Manager

Use TypeDB Studio’s schema manager to simplify schema editing, with a graphical interface for defining and visualizing the types in your data model and their properties. Create, maintain, explore, and extend schemas with ease.

Data Visualizer

TypeDB Studio features an interactive visualizer for query results in a hypergraph format. Explore your schemas and data, and discover the root causes of data inferred by the reasoning engine in an easy-to-access visual manner using TypeDB’s Explanations.

Powerful CLI

Database Administration

Access essential database management tools directly from the command line with TypeDB Console. Create and delete databases, build and extend schemas, or define and undefine rules with ease.

Access Control

TypeDB Console simplifies user access control by providing a powerful command line tool, allowing administrators to easily grant or restrict access, and reset their passwords.

Data Management

TypeDB Console allows you to easily insert, modify, and query your data, enabling you to interface directly with the database to rapidly fix issues in production.

Resilient Clustering

Automated Failover

TypeDB’s automatic failover ensures continual service by seamlessly switching to a backup node if the primary becomes unresponsive, minimizing downtime and preventing data loss.

Automated Load Balancing

Active-active clustering in TypeDB distributes read transactions across all active nodes to evenly balance the workload, ensuring efficient use of resources, strong consistency, and high availability.

Resilient Sessions

All TypeDB clients have built-in session resiliency for communication with TypeDB clusters. If a client has an open session to a node that goes down, the session is seamlessly reallocated to another node when a new transaction is opened.

Cluster Resizing

Easily resize TypeDB clusters by seamlessly adding or removing nodes without any downtime, using the CLI for TypeDB Enterprise and GUI for TypeDB Cloud. TypeDB Cloud deployments can also be configured to resize automatically based on load.

Secured Environment

User Authentication

TypeDB includes robust password authentication with customizable policies for controlling password length, complexity, and expiration.

Network Encryption

TypeDB ensures ironclad security by employing TLS 1.3 with user-provided certificates, safeguarding client-server communication with robust network encryption.

Audit Logs

The security of TypeDB is enhanced through audit logs, keeping track of authentication events, user and database management events, sessions and transactions opened, and queries executed.

User Authorization

Restrict database management and querying permissions granted to users in your organization by assigning them roles.

Easy Management

Fully Managed

Enjoy all the features of TypeDB Enterprise with a fully managed service in the cloud. Deploy in minutes with the click of a button, and rest easy in the knowledge that nodes will automatically recover in the event of failure.

Cloud Agnostic

TypeDB offers global coverage across multiple platforms, ensuring seamless accessibility and optimal performance for your data-driven success. Deploy on AWS or GCP, with support for MS Azure coming soon.

Collaborative Tools

Manage data across your users, teams, and organizations with TypeDB’s collaborative tools. Create projects to group deployments and control project access on a per-user or per-team basis.

Full Web Inteface

TypeDB simplifies cloud instance management with a real-time web interface, serving as a powerful control panel for deployment and control of managed clusters. Manage projects, deployments, teams, and users, as well as access support.

Seamless Upgrades

Upgrade your TypeDB databases to the most recent version with no downtime and with all schema and data migrations automatically handled.

Seamless Backups

Backup and restore TypeDB databases using the CLI for TypeDB Enterprise and the GUI for TypeDB Cloud.

Get started today

Deploy locally or in the cloud and start building now, or explore more about TypeDB and how its unique capabilities as a polymorphic database can refine and empower your applications.

Start building

Cloud or container, a polymorphic database with a conceptual data model, a strong subtyping system, a symbolic reasoning engine, and a type-theoretic language is minutes away.

Deploy
Feedback