Models define the data structure and data validation rules of your applications. A model is composed of basic, advanced, and sub-model fields. As an analogy, you can think of models as tables and fields as columns in relational databases or models as documents and fields as document properties in non-relational databases.
You can define model hierarchies where the top-level model can have several sub-models, and each sub-model can also have several other child models.
For example, for an e-commerce application, you can design the data structure of your users with a top-level user model with profile, shipping address, billing address, etc. sub-models. Additionally, you can have models for orders and products.
Models can be created either permanent or transient. Permanent models are stored in the database, whereas transient models are not. Transient models are usually used to define the input data structure for services.
You can think of models as templates or definitions for objects. When an entity of a specific model is created, meaning fields have values assigned; then, we call these entities objects. Objects are instances of models with specific field values, and usually objects are stored in the database. Each object is also a JSON document, namely key-value pairs.
Fields are the building blocks of a model. There are various field types that you can use in defining your data model structure. Fields also have the following common properties, and when creating a new field for a model, you need to decide on these properties.
- A field can be permanent or transient. Permanent fields are stored in the database, whereas transient fields are not. For example, you can store the first name and last name of a customer in the database but define a transient field named full name, which basically concatenates first and last name to come up with the full name. In this case, you do not need to store the full name in the database but set it as transient and define a default value expression that does the concatenation.
- A field can be indexed. Altogic automatically creates the necessary indices for your data model; however, for finer control over your data, you can explicitly specify whether to index the values of a field for faster access or not. Please note that while indexing helps speed up your data queries, they consume additional storage space.
- A field can be read-only. When an object with read-only fields is created, you cannot modify the value of read-only fields later. For example, you can define the account creation date or join date of a user as read-only, which should not change after a user is created.
- A field can be required or optional. Some of the values of a model could be nice to have but not mandatory. As an example, for a user model, it might be good to have the occupation information. In this case, you can model the occupation field as optional, and during object creation and object updates, no value existence checks are applied to this field.
- A field value can be returned or omitted in RESTful API responses. This is useful in managing sensitive data. For example, you can store users' passwords in the database but would not prefer to return the password field value, even encrypted, in service responses. In this case, you can mark these fields with sensitive data as omitted. Even a field is marked as omitted, you can still use it in expressions.
- A text or rich-text field can be searchable to enable text search of string content.
- A text or rich-text field can be full-text (fuzzy) searchable to allow fine grained text indexing and fuzzy searches.
- A field can have a default value expression. You can use the expression editor to write down Excel-like formulas in defining a field's default value. With expressions, you are not restricted to define default values as static values. You can define default values that can dynamically change based on the values provided in other model fields.
- A field can have validation rules. For each different field type, you can use pre-defined standard validation rules (e.g., a password text field cannot be shorter than 8 characters and cannot be longer than 40 characters, accept only positive integers) that are specific to the type of the field, or you can define your custom validations rules. Custom validation rules are defined as rule and error message expression pairs. When the validation rule expression fails (evaluates to false), the error message expression is evaluated and returned.
Text fields are used to store textual information. Using this field, you can store short textual information (max 512 characters) such as names, usernames, occupations, etc.
When defining a new text field, you can specify standard validation rules of which character types to include or exclude, min and max length, and define trimming and text transformation rules.
|Object id||Objects ids are used to store 24 characters long identifiers consisting of letters and numbers with a predefined format. Object ids are mainly text fields with custom id format control.|
|Rich text||Rich text fields are used to store longer text values such as blog posts, paragraphs, etc. A rich text field can be a maximum of 65536 characters long.|
|Encrypted text||Encrypted text fields are particularly useful in storing sensitive data such as passwords. An encrypted field can be a maximum of 50 characters long, and an encrypted value cannot be decrypted. Instead, encrypted values can be compared against non-encrypted values to check whether the two values do match or not.|
|As its name implies, email fields are used to store email data. They are basically a text field with a custom email validation rule.|
|Link||Link fields are used to store URL data. They are a text field with a custom a URL validation rule.|
|Boolean||Stores basic true or false values.|
|Integer||Stores whole numbers, no fractional components. You can specify whether an integer can be positive, negative, or can take zero value and define the min and max range.|
Stores number with fractional components. Like integers, you can specify whether a decimal can be positive, negative, or can take zero value and define the min and max range.
For decimal numbers, you can also set the decimal digits count and the rounding rule to apply if the decimal digits are longer than the set value.
|Monetary||Captures fractional units of currency and emulates decimal rounding with exact precision when performing arithmetic operations. This field type does not approximate decimal values and is able to provide the exact precision required for working with monetary data.|
|Date-time||Stores date and time values in ISO 8601 format (e.g., 2021-05-25T15:08:34.345+03:00)|
If you perform artichmetic operations on monetary values and use decimal or interger values in your expression or database queries, you need to convert integer and decimal values to monetary values using the MONETARY function.
|Auto number||Automatically generated integers. Auto-number fields start from a base number, and each time a new object with an auto-number field is created incremented by the increment value. You can use auto-number values to assign unique number values to objects. By default, auto number fields are required and read-only since they are always populated, and their values are managed internally by Altogic.|
Stores basically text values, but the values are primarily constrained from a list of options. The options list defines the list of values that can be assigned to a field. The options list field can be configured to select only a single option or multiple options. For example, an options list can be used to model a user's account status such that the user account can be in 'pending,' 'active,' 'suspended,' or 'deactivated' state. All these different status values can be defined as options, and only one of the values from these options can be configured to be selected.
You can also allow an option not specified in the options list to be assigned as the field value. Single option list fields are stored as a text field, and multi-options are stored as an array (list) of text values.
Please note that once the options list is specified, it is not possible to change its type; e.g., you cannot change a single value option list to multiple options or vice-versa.
|Geo point||Stores geographic point coordinates of a location as a list of longitude and latitude pairs. You can customize the precision decimal digits of longitude and latitude pairs.|
|Object reference||In some cases, you might need to have a reference to other model or sub-model objects in your data models. Object references are used to set up these relationships. When you have an object reference, you need to provide the correct referenced object identifier during create and update operations. In addition, with object references, you can do lookups (left-outer join) when retrieving data and use these looked-up values in your expressions.|
|Basic values list||As its name implies, basic values list is used to store an array (list) of basic data types. The basic data type can be either |
Stores reference to a document, image, audio, video, etc., files. When you upload a file, Altogic automatically generates a unique file identifier that provides access to the stored file and its metadata. The file reference field is used to store these file reference identifier values.
As an example for users, you may want to store the profile image of each user. You can add a file reference field to the user model, which basically references the uploaded user profile image.
|Object||Manages a single sub-model. For example, when modeling a user object, you can choose to model profile information under a profile object. Object fields are tightly coupled with their parent model, meaning when an object of the parent model is deleted, then the sub-model object is also deleted.|
Manages multiple sub-models. For example, a user model might have an addresses object list to model multiple user addresses. Therefore, when you query a user object, you also automatically get the addresses list of the queried user.
Object list fields are tightly coupled with their parent model, meaning when a parent model object is deleted, then the sub-model objects are also deleted. If you think the number of sub-model objects is limited (e.g., in tens or hundreds), then you can use an object-list field to model these cases. However, if you think the number of sub-model objects does not have any limits (e.g., thousands, millions), it is recommended to use a separate model to handle these cases.
Please refer to data modeling best practices to better understand your options and limitations of sub-model usage.