VariableTypes are used to define the substructure, semantic and DataType of Variables. Defining VariableTypes only makes sense, if it is expected that the VariableType is used several times. Variables are typically defined in the context of an ObjectType which already defines the semantic of the Variable. Therefore, often the VariableTypes of the base specification (specifically OPC 10000-8 with VariableTypes providing ranges and engineering unit) are sufficient and no new VariableTypes need to be defined.
OPC UA distinguishes between light-weight Variables called Properties and DataVariables (see OPC 10000-3).
Properties are expected to describe the Node they belong to and have several special rules (see OPC 10000-3). They are always of VariableType PropertyType (which is not allowed to be subtyped) and referenced with a HasProperty Reference. The BrowseName defines the sematic. They are the leaf of any hierarchy, meaning they cannot be the source of any hierarchical Reference and therefore not have any Properties by themselves.
Property values typically don’t change very often, and are usually read once and not subscribed to for changes.
DataVariables are of VariableType BaseDataVariableType or any subtype and do not have the restrictions of the Properties.
The decision to use a Property or DataVariable can to a certain degree be made on a semantic level. If the value describes the Node (like the engineering unit of a Variable), it is a Property; if it is something from the real world (like a measured temperature), it is a DataVariable. However, making the decision based on the semantic is not always that clear.
There are also the functional differences between Property and DataVariable. If your Variable needs Properties (like the engineering unit), you have to use a DataVariable, even if the semantic suggests that it should be defined as a Property.
As Properties have limited functionality, the recommendation is to use Properties when it is clear from the semantic that it is just describing the characteristics of the Node and there is no need to add additional information to the Variable, also not as extensible mechanism in vendor-models or other Companion Specifications. Otherwise, it is recommended to use DataVariables.
Nodes in OPC UA have a predefined set of Attributes. They are not extensible by Companion Specifications, only the base specification may add new optional Attributes over time. If there is the need to add more description to a Node, a Property needs to be used. Common Properties are EngineeringUnits or InstrumentRange.
When considering defining a Property, check the set of Attributes defined in the base specification to determine if one of them is suitable. For example, instead of defining a Property called Description, use the corresponding Attribute. OPC UA allows all Attributes to be writable, so even if the requirement is to have a writeable description, the Attribute can be used, and no additional Property should be defined.
VariableTypes can be used to define the semantic and substructure of a Variable. A common example is the AnalogItemType providing the EngineeringUnits and InstrumentRange Properties. Sometimes, it may be helpful to define a VariableType just to describe the semantic, for example a VariableType representing SetPoints. This makes sense if the same VariableType is intended to be used in various places. The semantic of a Variable used in an ObjectType is already defined by the ObjectType and does not need to have a specific VariableType.