Before we start talking about databases and different data models that exist, first we'd better talk about what a database is and how to use it. A database is an organized collection of data stored and accessed electronically. It is used to store and retrieve structured, semi-structured, or raw data which is often related to a theme or activity. At the heart of every database lies at least one model used to describe its data. And depending on the model it is based on, a database may have slightly different characteristics and store different types of data. To write, retrieve, modify, sort, transform or print the information from the database, a software called Database Management System (DBMS) is used. The size, capacity, and performance of databases and their respective DBMS have increased by several orders of magnitude. It has been made possible by technological advances in various areas, such as processors, computer memory, computer storage, and computer networks. In general, the development of database technology can be divided into four generations based on the data models or structure: navigational, relational, object and post-relational. ![](/sites/default/files/inline/images/images/image-20220710225128-1.png)![](/sites/default/files/inline/images/images/image-20220710225128-2.png) Unlike the first three generations, which are characterized by a specific data model, the fourth generation includes many different databases based on different models. They include column, graph, document, component, multidimensional, key-value, in-memory etc. All these databases are united by a single name NoSQL (No SQL or now it is more accurate to say Not only SQL). Moreover, now a new class appears, which is called NewSQL. These are modern relational databases that aim to provide the same scalable performance as NoSQL systems for online transaction processing workloads (read-write) while using SQL and maintaining ACID. Incidentally, among these fourth generation databases are those that support multiple data models mentioned above. They are called multi-model databases. A good example of this type of database is InterSystems IRIS. That is why I will use it to give examples of different types of models as they appear.

The first generation databases used hierarchical or network models. At the heart of the former is a tree structure where each record has only one owner. You can see how this works using the example of InterSystems IRIS, because its main model is hierarchical and all data is stored in globals (which are B*-trees). You can read more about globals here.

We can create this tree in IRIS :
<span class="hljs-keyword">Set</span> <span class="hljs-symbol">^a</span>(<span class="hljs-string">"+7926X"</span>, <span class="hljs-string">"city"</span>) = <span class="hljs-string">"Moscow"</span>
<span class="hljs-keyword">Set</span> <span class="hljs-symbol">^a</span>(<span class="hljs-string">"+7926X"</span>, <span class="hljs-string">"city"</span>, <span class="hljs-string">"street"</span>) = <span class="hljs-string">"Req Square"</span>
<span class="hljs-keyword">Set</span> <span class="hljs-symbol">^a</span>(<span class="hljs-string">"+7926X"</span>, <span class="hljs-string">"age"</span>) = <span class="hljs-number">25</span>
<span class="hljs-keyword">Set</span> <span class="hljs-symbol">^a</span>(<span class="hljs-string">"+7916Y"</span>, <span class="hljs-string">"city"</span>) = <span class="hljs-string">"London"</span>
<span class="hljs-keyword">Set</span> <span class="hljs-symbol">^a</span>(<span class="hljs-string">"+7916Y"</span>, <span class="hljs-string">"city"</span>, <span class="hljs-string">"street"</span>) = <span class="hljs-string">"Baker Street"</span>
<span class="hljs-keyword">Set</span> <span class="hljs-symbol">^a</span>(<span class="hljs-string">"+7916Y"</span>, <span class="hljs-string">"age"</span>) = <span class="hljs-number">36</span>
And see it in the database:

After Edgar F. Codd proposed his relational algebra and his theory of data storage, using relational principles, in 1969. After, **the relational databases** were created. The use of relations (tables), attributes (columns), tuples (rows), and, most importantly, transactions and ACID requirements made these databases very popular and they remain so now. For example, we have the schema:

We can create and populate tables:

And if we write the query:
select p.ID, p.Name, a.Country, A.City
  from My.Person p left join My.Address a
    on p.Address = a.ID
we will receive the answer:

Despite the significant advantages of relational databases, with the spread of object languages, it became necessary to store object-oriented data in databases. That's why in the 1990s the first **object-oriented** and object-relational databases appeared. The latter were created on the basis of relational databases by adding add-ons to simulate the work with objects. The former were developed from scratch based on the recommendations of the OMG (Object Management Group) consortium and after ODMG (Object Data Management Group). The key ideas of these object-oriented databases are the following. The single data warehouse is accessible using: * object definition language - schema definition, allows defining classes, their attributes, relations, and methods, * object-query language - declarative, almost SQL-like language that allows getting objects from the database, * object manipulation language - allows modification and saving data in the database, supports transactions and method calls. This model allows obtaining data from databases using object-oriented languages. If we take the same structure as in the previous example but in the object-oriented form, we will have the following classes:
<span class="hljs-keyword">Class</span> My.Person <span class="hljs-keyword">Extends</span> <span class="hljs-built_in">%Persistent</span>
{
<span class="hljs-keyword">Property</span> Name <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Name</span><span class="hljs-comment">;</span>
<span class="hljs-keyword">Property</span> Address <span class="hljs-keyword">As</span> My.Address<span class="hljs-comment">;</span>
}
<span class="hljs-keyword">Class</span> My.Address <span class="hljs-keyword">Extends</span> <span class="hljs-built_in">%Persistent</span>
{
<span class="hljs-keyword">Property</span> Country<span class="hljs-comment">;</span>
<span class="hljs-keyword">Property</span> City<span class="hljs-comment">;</span>
}
And we can create the objects using the object-oriented language:
 <span class="hljs-keyword">set</span> address = <span class="hljs-keyword">##class</span>(My.Address).<span class="hljs-built_in">%New</span>()
 <span class="hljs-keyword">set</span> address.Country = <span class="hljs-string">"France"</span>
 <span class="hljs-keyword">set</span> address.City = <span class="hljs-string">"Marseille"</span>
 <span class="hljs-keyword">do</span> address.<span class="hljs-built_in">%Save</span>()
 <span class="hljs-keyword">set</span> person = <span class="hljs-keyword">##class</span>(My.Person).<span class="hljs-built_in">%New</span>()
 <span class="hljs-keyword">set</span> person.Address = address
 <span class="hljs-keyword">set</span> person.Name = <span class="hljs-string">"Quouinaut, Martin"</span>
 <span class="hljs-keyword">do</span> person.<span class="hljs-built_in">%Save</span>()
Unfortunately, object databases did not succeed in competing with relational databases from their dominant position, and as a result, many ORMs appeared. In any case, with the spread of the Internet in the 2000s and the emergence of new requirements for data storage, other data models and DBMSs started to emerge. Two of these models that are used in IRIS are document and column models. **Document-oriented databases** are used to manage semi-structured data. This is data that does not follow a fixed structure and carries the structure within it. Each unit of information in such a database is a simple pair: a key and a specific document. This document is formatted usually in JSON and contains the information. Since the database does not require a certain schema, it is also possible to integrate different types of documents in the same warehouse. If we take the previous example again, we can have documents like these:
{
   <span class="hljs-string">"Name"</span>:<span class="hljs-string">"Quouinaut, Martin"</span>,
   <span class="hljs-string">"Address"</span>:{
      <span class="hljs-string">"Country"</span>:<span class="hljs-string">"France"</span>,
      <span class="hljs-string">"City"</span>:<span class="hljs-string">"Paris"</span>
   }
}
{
   <span class="hljs-string">"Name"</span>:<span class="hljs-string">"Merlingue, Luke"</span>,
   <span class="hljs-string">"Address"</span>:{
      <span class="hljs-string">"Country"</span>:<span class="hljs-string">"France"</span>,
      <span class="hljs-string">"City"</span>:<span class="hljs-string">"Nancy"</span>
   },
   <span class="hljs-string">"Age"</span>:<span class="hljs-number">26</span>
}
These two documents with a different number of fields are stored in the IRIS database without any problem. And the last example of a model that will be available in version 2022.2 is the **column model**. In this case, the DBMS stores the data tables per column and not per row.

Column orientation allows more efficient access to data for querying a subset of columns (eliminating the need to read columns that are not relevant), and more options for data compression. Compression by column is also more efficient when the data in the column is similar. However, they are generally less efficient for inserting new data. You can create this table:
Create Table My.Address (
  city varchar(<span class="hljs-number">50</span>),
  zip varchar(<span class="hljs-number">5</span>),
  country varchar(<span class="hljs-number">15</span>)
) WITH STORAGETYPE = COLUMNAR
In this case, the class is like this:
 
Spoiler
 
<span class="hljs-keyword">Class</span> My.Address <span class="hljs-keyword">Extends</span> <span class="hljs-built_in">%Persistent</span> [ ClassType = persistent, DdlAllowed, Final, Owner = {UnknownUser}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = Address ]
{
<span class="hljs-keyword">Property</span> city <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Library.String</span>(COLLATION = <span class="hljs-string">"EXACT"</span>, MAXLEN = <span class="hljs-number">50</span>) [ SqlColumnNumber = <span class="hljs-number">2</span> ]<span class="hljs-comment">;</span>
<span class="hljs-keyword">Property</span> zip <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Library.String</span>(COLLATION = <span class="hljs-string">"EXACT"</span>, MAXLEN = <span class="hljs-number">5</span>) [ SqlColumnNumber = <span class="hljs-number">3</span> ]<span class="hljs-comment">;</span>
<span class="hljs-keyword">Property</span> country <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Library.String</span>(COLLATION = <span class="hljs-string">"EXACT"</span>, MAXLEN = <span class="hljs-number">15</span>) [ SqlColumnNumber = <span class="hljs-number">4</span> ]<span class="hljs-comment">;</span>
<span class="hljs-keyword">Parameter</span> STORAGEDEFAULT = <span class="hljs-string">"columnar"</span><span class="hljs-comment">;</span>
<span class="hljs-keyword">Parameter</span> USEEXTENTSET = <span class="hljs-number">1</span><span class="hljs-comment">;</span>
<span class="hljs-comment">/// Bitmap Extent Index auto-generated by DDL CREATE TABLE statement.  Do not edit the SqlName of this index.</span>
Index DDLBEIndex [ Extent, SqlName = <span class="hljs-string">"%%DDLBEIndex"</span>, Type = bitmap ]<span class="hljs-comment">;</span>
Storage Default
{
<Data name=<span class="hljs-string">"_CDM_city"</span>>
<Attribute>city</Attribute>
<ColumnarGlobal><span class="hljs-symbol">^q3AW</span>.DZLd.1.V1</ColumnarGlobal>
<Structure>vector</Structure>
</Data>
<Data name=<span class="hljs-string">"_CDM_country"</span>>
<Attribute>country</Attribute>
<ColumnarGlobal><span class="hljs-symbol">^q3AW</span>.DZLd.1.V2</ColumnarGlobal>
<Structure>vector</Structure>
</Data>
<Data name=<span class="hljs-string">"_CDM_zip"</span>>
<Attribute>zip</Attribute>
<ColumnarGlobal><span class="hljs-symbol">^q3AW</span>.DZLd.1.V3</ColumnarGlobal>
<Structure>vector</Structure>
</Data>
<DataLocation><span class="hljs-symbol">^q3AW</span>.DZLd.1</DataLocation>
<ExtentLocation><span class="hljs-symbol">^q3AW</span>.DZLd</ExtentLocation>
<ExtentSize><span class="hljs-number">3</span></ExtentSize>
<IdFunction>sequence</IdFunction>
<IdLocation><span class="hljs-symbol">^q3AW</span>.DZLd.1</IdLocation>
<Index name=<span class="hljs-string">"DDLBEIndex"</span>>
<Location><span class="hljs-symbol">^q3AW</span>.DZLd.2</Location>
</Index>
<Index name=<span class="hljs-string">"IDKEY"</span>>
<Location><span class="hljs-symbol">^q3AW</span>.DZLd.1</Location>
</Index>
<IndexLocation><span class="hljs-symbol">^q3AW</span>.DZLd.I</IndexLocation>
<<span class="hljs-keyword">Property</span> name=<span class="hljs-string">"%%ID"</span>>
<AverageFieldSize><span class="hljs-number">3</span></AverageFieldSize>
<Selectivity><span class="hljs-number">1</span></Selectivity>
</<span class="hljs-keyword">Property</span>>
<<span class="hljs-keyword">Property</span> name=<span class="hljs-string">"city"</span>>
<AverageFieldSize><span class="hljs-number">7</span></AverageFieldSize>
<Selectivity><span class="hljs-number">33.3333</span>%</Selectivity>
</<span class="hljs-keyword">Property</span>>
<<span class="hljs-keyword">Property</span> name=<span class="hljs-string">"country"</span>>
<AverageFieldSize><span class="hljs-number">7</span></AverageFieldSize>
<Selectivity><span class="hljs-number">33.3333</span>%</Selectivity>
</<span class="hljs-keyword">Property</span>>
<<span class="hljs-keyword">Property</span> name=<span class="hljs-string">"zip"</span>>
<AverageFieldSize><span class="hljs-number">7</span></AverageFieldSize>
<Selectivity><span class="hljs-number">33.3333</span>%</Selectivity>
</<span class="hljs-keyword">Property</span>>
<SQLMap name=<span class="hljs-string">"%%DDLBEIndex"</span>>
<BlockCount>-<span class="hljs-number">4</span></BlockCount>
</SQLMap>
<SQLMap name=<span class="hljs-string">"IDKEY"</span>>
<BlockCount>-<span class="hljs-number">4</span></BlockCount>
</SQLMap>
<SQLMap name=<span class="hljs-string">"_CDM_city"</span>>
<BlockCount>-<span class="hljs-number">4</span></BlockCount>
</SQLMap>
<SQLMap name=<span class="hljs-string">"_CDM_country"</span>>
<BlockCount>-<span class="hljs-number">4</span></BlockCount>
</SQLMap>
<SQLMap name=<span class="hljs-string">"_CDM_zip"</span>>
<BlockCount>-<span class="hljs-number">4</span></BlockCount>
</SQLMap>
<StreamLocation><span class="hljs-symbol">^q3AW</span>.DZLd.<span class="hljs-keyword">S</span></StreamLocation>
<Type><span class="hljs-built_in">%Storage.Persistent</span></Type>
}
}
 
Then we insert the data:
insert into My.Address values ('London', '<span class="hljs-number">47000</span>', 'UK')
insert into My.Address values ('Paris', '<span class="hljs-number">54000</span>', 'France')
insert into My.Address values ('Kyiv', '<span class="hljs-number">03000</span>', 'Ukraine')
In the globals we see:

If we open the global with the city names, we will see :

And if we write a query:
select City
  from My.Address
we receive data:

In this case, the DBMS just reads a global to get the whole result. And it saves time and resources when reading. So, we have talked about 5 different data models supported by the InterSystems IRIS database. These are the hierarchical, relational, object, document, and column models. Hope you will find this article useful when trying to figure out which models are available. If you have any questions feel free to ask them in the comments.