The power of first-class Attributes: When every fish is aquatic, but not everything aquatic is a fish.

Since stepping in as CEO, I’ve made a point of getting into TypeDB properly, and really understanding how it actually works. Coming from a product background, getting deep into the product is important to me. As I go, I’m going to start sharing the things I find genuinely interesting and unique. This week: the elegance of first-class attributes.
What are data attributes?
In almost every database, describing something means attaching data to an object. In SQL, you add a value in a column. In a graph database, you add a property to a node. This information lives on the record it describes, and that feels natural since it keeps a concept close to the thing it relates to. So, a user may have an email attribute, or a created_at date.
The problem appears when you want to go the other way. Say you have a graph database full of animals and have labelled each with its preferred habitat. Now, you want to find every aquatic species. Fish are obvious. But dolphins are mammals. Crocodiles are reptiles. Certain insects, certain spiders. “Aquatic” cuts across every category in the database, but because each animal just carries its own isolated copy of that label, there is nothing connecting them. You have to know in advance which categories to search, and query each one separately, and hope you haven’t missed any, and hope there are no mis-typed labels. The attribute is everywhere and nowhere at the same time.
This is how almost every database works. It is also, when you think about it, a rather strange way to model the world.
Attributes as a first-class citizen
In TypeDB, you can define a habitat attribute, and “aquatic” becomes a value that anything in that world can share, rather than an isolated label repeated across thousands of records. This becomes a first-class concept with its own identity. Anything in the database that can have a habitat can use it without you needing to redefine it for each one.
From that point on, every instance in the database with an “aquatic” habitat connects to the same instance of that attribute. There are not thousands of copies scattered across thousands of records. There is just one, and everything that shares it is, by that fact, connected to it.
This means you can ask the question the other way around. Rather than searching across every entity type to find ones with an “aquatic” habitat, you start from the attribute itself and ask ‘what has a habitat that is aquatic?’ The query doesn’t need to know in advance which categories to search, because the attribute holds the answer.
What inheritance adds
This model becomes even more powerful when you look at how attributes cascade through inheritance. Imagine structuring your database like a series of trees.
At the top, you may have broad categories; animals, plants, regions. Below them, more specific ones; mammals, fish, reptiles. Below those, more specific still; dolphins, salmon, crocodiles. Each level inherits the properties of the one above it.
In TypeDB, once you define a “habitat” attribute, you can then attach it to whatever level of the tree makes sense, or even multiple different trees at once. Attach it to “animal” and every mammal, fish, reptile, and bird in the database gains the ability to have a habitat. You don’t need to declare it separately for dolphins, or for bottlenose dolphins, or for every individual species below that. The tree carries it down automatically.
This means that when you declare a bottlenose dolphin has an aquatic habitat, you’re using an attribute that has been created and defined on an entity several levels up the schema. This type of inheritance saves you from creating a new “habitat” field for every entity in your database.
A more familiar example; think of a SQL eCommerce database. Normally, you would create an email field for the buyer table, seller table, admin user table, team table, and many others. In TypeDB, you would create an email attribute, and attach it to “Users”. Buyers, sellers, admin staff, and team members are all simply a sub-entity of user. This would allow you to create an email for a buyer, without ever specifying that buyers have email addresses.
Two levels, one principle
These are actually two distinct capabilities that compound each other. At the schema level, inheritance means you define which things can hold an attribute once, at the right level of the hierarchy, and everything below it gains that connection automatically. At the data level, first-class attributes mean you insert a value once, and every entity connected to it shares the same instance; no duplication, no divergence.
Define once. Connect everywhere. Insert once. Connect to everything.
Most databases require you to solve both problems manually. In TypeDB, they are solved by the model itself.
What happens when your database grows
Because the habitat attribute exists independently of any category, extending the database doesn’t require revisiting it. Say you want to add plants as a new class of entities and sub-entities in the database. You define the new tree, attach the habitat attribute at the top level, and every species below it (trees, flowers, grasses) immediately inherits the ability to carry it, and participates in the same connected structure as everything else.

The queries that were already working now reach further, without any modification. The same attribute, defined once, now spans two entirely separate trees. And the questions you can ask become more precise. Fetch me all aquatic species that are not fish. Fetch me all aquatic plants. Fetch me mammals that are aquatic but also spend significant time on land. The attribute becomes a lens you can combine with any other lens in the database to extract knowledge and build reasoning.
Why this matters beyond elegance
The animal kingdom is a convenient illustration, but the principle applies anywhere you have properties that cut across categories. In an organisation, a security clearance level applies to people, to systems, to physical locations, and to documents; it isn’t owned by any one of them, it’s a shared concept they all participate in. In a company database, an email address is a unique value that may be used in multiple different places and systems. In a supply chain, a certification standard applies to suppliers, products, manufacturing facilities, and shipping routes simultaneously.
In most databases, modelling these relationships requires deliberate engineering. You create junction tables, or intermediate nodes, or duplicate values and hope they stay in sync. The connections between things that share a property are something you have to build, and maintain, and query carefully.
In TypeDB, they are a consequence of how the data is structured. Define the attribute and attach it where it belongs. Extend as needed. TypeDB allows you to compose your data model exactly as you need it.
A different approach to modelling data
Most database models (relational, document, graph) were designed around the assumption that data describes things. TypeDB was designed around the assumption that data describes a world, and that the concepts in that world have their own existence, independent of the records they apply to.
First-class attributes are one of many ways we express that difference. They reflect a carefully researched and designed choice, made at the foundation, about what a database is actually for, and I find it rather elegant.



