---
title: "SurrealDB University's newest course: Schema internals and migrations"
description: "SurrealDB University's newest course teaches you about schema internals and migrations."
url: https://surrealdb.com/blog/surrealdb-universitys-newest-course-schema-internals-and-migrations-2
date: 2026-08-18
authors: "Dave MacLeod & Chiru Boggavarapu"
---

# SurrealDB University's newest course: Schema internals and migrations

![SurrealDB University's newest course: Schema internals and migrations](https://cdn.surrealdb.com/8mnqnv63rrbvokhdpcv04ku2.auto)

Today we are excited to announce SurrealDB University's newest course - the fifth one. SurrealDB University has been live for almost two years now, during which four courses were released which cover all the basics over a variety of ways to learn them depending on your learning preferences and available time.

Here are the first four courses and how their teaching style differs.

* [A Tour of SurrealDB](https://surrealdb.com/learn/tour): familiarise yourself with SurrealDB in as short a time as possible over 30-ish short pages. It was inspired by the famous [Tour of Go](https://go.dev/tour/welcome/1), which does the same for the Go language.
* [SurrealDB Fundamentals](https://surrealdb.com/learn/fundamentals): learn the ins and outs of SurrealDB and get a certificate at the end.
* [Aeon's Surreal Renaissance](https://surrealdb.com/learn/book): learn SurrealDB through a story that takes place in a medieval future about seven centuries from today. This one is by far the longest SurrealDB University course.
* [Movie database tutorial](https://surrealdb.com/learn/movies): a course that takes you step-by-step through constructing a database that holds data for the world's top-grossing movies, for those who prefer to learn by doing. It's a spinoff and expansion of the last four chapters of Aeon's Surreal Renaissance, so that you can build the final project in the book in greater depth without needing to get through the preceding 18 chapters or spoiling the story by starting at the final project section.

With those four courses, you can learn SurrealDB in your own preferred manner: quickly, formally, immersively, or actively.

We are now working on more modular courses that each focus on a specific area involved when running a SurrealDB instance. The first modular course is called [SurrealDB schema internals and migrations](https://surrealdb.com/learn/schemas), and as the title suggests is divided into two parts. They are:

## Schema internals

This section is about how to make the best use of SurrealQL to design a schema that lets you move as much logic as possible from the client side to the database itself. Embedding type safety, logic and even reactive functionality like events in the data lets you ensure that the software you build works the way you expect it to, regardless of the method or programming language you use to interact with it at higher levels.

The more you familiarise yourself with schema internals, the less work you have to do later on. For example, you can even define fields as the output of a separate expression and entirely do away with the need to write separate statements.

```surrealql
-- All users get a wallet with a balance of 50 by default,
-- no need for a separate CREATE statement
DEFINE FIELD wallet ON user DEFAULT CREATE ONLY account SET balance = 50;

-- All new staff are related as a 'member_of' the company,
-- the company name as a string becomes the field's value
DEFINE FIELD works_at ON staff DEFAULT
    (RELATE ONLY $this->member_of->organisation:my_company).out.name;
```

This section also includes advice on how to migrate your schema and the options available to you using raw SurrealQL. You can use defined functions for example to somewhat automate and track changes to a table's schema over time.

```surrealql
-- Call this function every time a schema is updated
DEFINE FUNCTION fn::update_schema($table: string) {
    UPDATE type::record("schema", $table) SET
    current = INFO FOR TABLE $table,
    history += {
        at: time::now(),
        diff: (INFO FOR TABLE $table).diff(schema:person.current)
    };
};
```

But once your project reaches a certain level of complexity you will want to reach for a tool that is specialised for the task, which in this case is known as SurrealKit and is the main focus of the course.

## Schema migrations (SurrealKit)

[SurrealKit](https://github.com/surrealdb/surrealkit) was released a few months ago and is SurrealDB's official migration tool. As the tool's readme puts it, it is divided largely into two types of schema migrations:

* Sync: a fast, declarative push for development. Your schema files are the source of truth - add a definition and it gets created, change it and it gets updated, remove it and it gets deleted.
* Rollouts: controlled, phased migrations for shared and production databases. Changes are planned into reviewed manifests, applied in stages, and can be rolled back.

The SurrealKit-based chapters in the course teach you how to use both sync and rollout as you gradually put a schema together over multiple files that ends up looking like the one below. This is one of the [sample industry schemas](https://surrealdb.com/docs/learn/schema-management/schema-design/sample-industry-schemas#project-planning) in our documentation that are each about 50 lines in length and can be used as scaffolding for a schema in many of the industries you will be using SurrealDB for. In this case, it's a schema built to manage project planning and all of its intricacies: activity start and end dates, who they are assigned to, which activities are dependent, milestone completion, and so on.

```surrealql
DEFINE TABLE project;

-- Activities in a project schedule
DEFINE TABLE activity SCHEMAFULL;
DEFINE FIELD name         ON activity TYPE string;
DEFINE FIELD description  ON activity TYPE option<string>;
DEFINE FIELD start        ON activity TYPE datetime;
DEFINE FIELD end          ON activity TYPE datetime;
DEFINE FIELD duration     ON activity COMPUTED end - start;
DEFINE FIELD progress     ON activity TYPE float ASSERT $value IN 0.0..=1.0;
DEFINE FIELD assigned_to  ON activity TYPE option<record<employee>>;
DEFINE FIELD followed_by  ON activity COMPUTED <-depends_on<-activity;

-- Milestones
DEFINE TABLE milestone SCHEMAFULL;
DEFINE FIELD project      ON milestone TYPE record<project>;
DEFINE FIELD activities   ON milestone TYPE array<record<activity>>;
DEFINE FIELD name         ON milestone TYPE string;
DEFINE FIELD last_updated ON milestone VALUE time::now();
DEFINE FIELD progress     ON milestone COMPUTED math::mean(activities.progress);
DEFINE FIELD is_complete  ON milestone COMPUTED activities.all(|$a| $a.progress > 0.95);

-- Graph-style dependency links
DEFINE TABLE depends_on SCHEMAFULL TYPE RELATION IN activity OUT activity;
DEFINE TABLE activity_of SCHEMAFULL TYPE RELATION IN activity OUT project;

CREATE project:one SET name = "Construction project";

CREATE activity:one SET name = "Project kickoff", start = time::now(), end = time::now() + 2d, progress = 1.0;
CREATE activity:two SET name = "Pour concrete", start = time::now() + 90d, end = time::now() + 100d, progress = 0.0;
CREATE activity:three SET name = "Dry concrete", start = time::now() + 100d, end = time::now() + 107d, progress = 0.0;
CREATE activity:four SET name = "Build on top of concrete", start = time::now() + 107d, end = time::now() + 150d, progress = 0.0;

RELATE activity:two->depends_on->activity:one;
RELATE activity:three->depends_on->activity:two;
RELATE activity:four->depends_on->activity:three;
RELATE [activity:one,activity:two,activity:three, activity:four]->activity_of->project:one;

CREATE milestone:one SET project = project:one, activities = [activity:one], name = "Project start";
CREATE milestone:two SET project = project:one, activities = [activity:two, activity:three, activity:four], name = "Initial construction";

-- See all graph connections between activity and project records
SELECT *, ->? AS joins_to, <-? AS joined_from FROM activity, project;

-- View the current milestones
SELECT * FROM milestone;
```

All in all, the course is 14 short lessons in length so you should be able to complete it in about a day or two.

We recommend slowing down as much as possible and running every command during the SurrealKit portions, because that will give you the best muscle memory possible for when it comes time to begin using it to track and migrate schemas for your own software. This is because schema migrations are by nature much less frequent than raw queries, which you can play around with all day in your own database if you feel so inclined in the same way as with any other programming language.

In fact, you can even solve Advent of Code puzzles as [one of our ambassadors has done before](https://www.youtube.com/watch?v=wfq8gcXDK40).

![](https://cdn.surrealdb.com/w(1600)q(80)/u2e9dz01i8mq2alzd0s3wpmq.auto)

Since schema migrations don't provide the same jolt of dopamine you get when viewing the results of raw queries, hopefully the construction of a working schema will be a fun enough challenge to get through learning the intricacies of schema management using SurrealKit.

And if you are up for a challenge, try [selecting a different schema](https://surrealdb.com/docs/learn/schema-management/schema-design/sample-industry-schemas) from the sample industry schemas we have available and see if you can build that instead of the project planning one included in the course! The [bank schema](https://surrealdb.com/docs/learn/schema-management/schema-design/sample-industry-schemas#general-bank-schema-graph-schema) is another particularly nice one.

## Let us know what you think

SurrealDB University is shaped by the community. We are always eager to hear your thoughts and feedback in order to further improve the experience.

You can submit suggestions and requests on our [Suggestion Hub](https://github.com/surrealdb/suggestions/discussions/), or [Join us on Discord](https://discord.com/invite/surrealdb) to discuss further (#help or #surrealkit are two good channels), share what you're building, or tell us what you'd like to see next.

Get started for free today at [studio.surrealdb.com](https://studio.surrealdb.com).
