Pending completion
Define tables, views and changefeeds
In this lesson, we'll cover:
How to define schemaless and schemafull tables
The different table types
Pre-computed table views
Change feeds
Table permissions
Defining schemaless tables
We'll start by defining schemaless tables, or rather exploring the schemaless tables we've already defined so far.
We'll do this with the INFO statement, which gives us information about things we can DEFINE or have already defined.
When we run the query INFO FOR DB, we'll see everything that can be defined at the level of the database. Right now we're just going to focus on the tables.
When looking at the results, we can see that we've defined multiple schemaless tables, even though we never ran a DEFINE TABLE statement before.
The reason for this is because every time we CREATE a table, like have done multiple times up till now, SurrealDB behind the scenes does a DEFINE TABLE for that table. The reasons why SurrealDB can DEFINE a schema for a schemaless table is because it's not just either or. You can have mixed tables where some parts are schemaless and some parts are schemafull, we'll explore this more fully in our next lesson when we look at the DEFINE FIELD statement in more detail.
Defining schemafull tables
In order to make tables schemafull, we use the SCHEMAFULL clause on the DEFINE TABLE statement. When a table is defined as schemafull, the database strictly enforces the schema we've defined. That means that a value can't be set to a field on a SCHEMAFULL table until it has been defined via the DEFINE FIELD statement.
The different table types
SurrealDB makes a distinction between three types of tables:
TYPE RELATIONis used to add a constraint to the table, only allowing graph relations.TYPE NORMALis also used to add a constraint to the table with the opposite effect, not allowing graph relations.TYPE ANYallows both graph and non-graph data.
By default, a schemaless table will be of TYPE ANY while a schemafull table will be of TYPE NORMAL unless you set the type otherwise.
You can add further constraints to tables which are TYPE RELATION, specifying which tables they are related to.
There are two ways of specifying this:
Using
FROM .. TO, as an example,FROM person TO productUsing
IN .. OUT, as an example,IN product OUT product
Defining the schema using TYPE RELATION is the recommended way of defining graph relations. This means that you don't have to DEFINE the in or out fields using the DEFINE FIELD statement.
Pre-computed table views
In SurrealDB, like in other databases, you can create views. The way you create views is by using the DEFINE TABLE statement like you would for any other table, then adding the AS clause at the end with your SELECT query. Here's an example.
There are a few important things which make our views far more powerful than a typical relational database view and also a few limitations to keep in mind.
We'll start with what makes them powerful. Our pre-computed table views are most similar to event-based, incrementally updating, materialised views. That was a mouthful, so let's explain what that means.
Event-based: this means that when you add or remove data from the underlying table, in our example, the
reviewtable, it triggers a matching event on theavg_product_reviewtable view.Materialised view: this means that the first time we run the table view query, it will run the query like a normal
SELECTstatement, but then materialise the result. Contrast this with normal views which behave like bookmarkedSELECTqueries and just look like tables to the user.Incrementally updating: this means that for any subsequent run, it will listen for the event trigger and perform the most efficient operation possible to always keep the result up to date, instead of outright running the
SELECTstatement again.
While this functionality can be replicated in many other databases, it is usually only done by expert users as it can be very complicated to set up and maintain. Therefore, the true power of our pre-computed table views is in making this advanced functionality accessible to everyone.
As mentioned though, there are a few limitations to keep in mind.
First, while subsequent runs are very efficient, the initial run of large analytical queries can use a lot of resources, because it's just a normal
SELECTstatement. Therefore indexing and query optimisation are still very important.Second, while both graph relations and record links are supported, the table view update event only gets triggered based on the table we have in our
FROMclause. In our case, just thereviewtable, not theproductwe are also using in the query. Meaning that if you delete areviewtheavg_product_reviewwill reflect that in near real-time. However, if you delete aproduct, it will still show up inavg_product_review.
DROP tables can also be useful in combination with our pre-computed table views or custom events, as you can do computation on a record and then drop (delete) it in near real-time. A typical use case for this would be time-series or log data, where you only care about storing the aggregate information.
Another method that is a bit similar to table views is an event, which is some sort of behaviour that is triggered when a record is created, updated, or deleted. We don't cover events in this course but you can read about them in the documentation or see our other courses to learn more.
Changefeeds
Changefeeds can record and replay any change to the database, following the Change Data Capture pattern. This enables SurrealDB to play a role within the wider ecosystem of enterprise, cloud, or micro-service based platforms, giving users the ability to retrieve and sync changes from SurrealDB to external systems and platforms.
Changefeeds are defined using the CHANGEFEED clause followed by its duration for our table. After that it will start recording changes as we do any CRUD operation like we normally would.
An important thing to note is that even though in this example we just defined a CHANGEFEED on the product table, SurrealDB behind the scenes defines a CHANGEFEED on the entire database as well.
After doing some changes to the product table, we can replay them using the SHOW CHANGES FOR TABLE product. It's important to note that the SINCE <time> needs to be after the time the CHANGEFEED was defined.
Some typical use cases for Changefeeds include ingesting data into third-party systems, archiving data to object storage for backup or analysis purposes, or for real-time synchronisation with other platforms. Changefeeds are therefore a core feature for the enterprise.
Table permissions
We'll cover authentication in more detail in part 4, we'll just briefly touch on here that you can define table-level PERMISSIONS using the DEFINE TABLE statement.
You can see that you are able to set independent permissions for selecting, creating, updating, and deleting data. You can also however specify them all in one group.
Summary
Let's just briefly summarise what we've learned
The DEFINE TABLE statement allows us to define:
SCHEMALESSorSCHEMAFULLtablesThe three table types,
RELATION,NORMALandANYPre-computed table views using the
ASclause followed by theSELECTstatementChangefeeds, using the
CHANGEFEEDclauseTable level
PERMISSIONS, which can be done independently for each CRUD operation or all in one group.