At its core, the Globals database is powered by an extremely efficient multidimensional data engine. The exposed interface support access to the multidimensional structures – providing the highest performance and greatest range of storage possibilities. A multitude of applications can be implemented entirely using this data engine directly.
There is no data dictionary, and thus no data definitions, for the multidimensional data engine.
A global is a persistent sparse multi-dimensional array, which consists of one or more storage elements or "nodes". Each node is identified by a node reference (which is, essentially, its logical address). Each node consists of a name (the name of the global to which this node belongs) and zero or more subscripts.Here is an example of a simple global with no subscripts:
simpleGlobal =="some data"
A node reference with just a name and no subscripts identifies the root node of a global. Node references with a name and one subscript identify the first level of nodes in the global, and in general node references with N subscripts identify the Nth level of nodes in the global.
A node may contain data (up to 2 megabytes), or it may have one or more descendants, or "subnodes", or it may contain data and also have subnodes.
The name of a global is always a String. The name must be unique within the first 31 characters, the first character must be a letter (upper or lower case), and the remaining characters may be letters, digits, or a period ('.').
Subscripts may be of any of the types String, int, long, or double. Subscripts of any of these types can be mixed among the nodes of the same global, at the same or different levels. An example of a more complex global, with two subscripts, is show below:
moreComplexGlobal["subscript-1", "subscript-2"] =="some data"
The data value of a global node can be of any of the types String, int, long, double, byte[], or an encoded list of any of these types, which is encapsulated in the class ValueList. ValueList provides methods for appending elements of any of these types to a list, and getting items from a list, providing efficient, transparent serialization/deserialization.
Data can be stored in a global with any number of subscripts. What's more, subscripts are typeless and can hold any sort of data. One subscript might be an integer, such as 34, while another could be a meaningful name, like “LineItems” – even at the same subscript level.
For example, a stock inventory application that provides information about item, size, color, and pattern might have a structure like this:
stock[item,size,color,pattern] == quantity
Here's some sample data:
stock[“slip dress”,4,”blue”,”floral”] == 3
With this structure, it is very easy to determine if there are any size 4 blue slip dresses with a floral pattern – simply by accessing that data node. If a customer wants a size 4 slip dress and is uncertain about the color and pattern, it is easy to display a list of all of them by cycling through all the data nodes below:
stock[“slip dress”,4]
In this example, all of the data nodes were of a similar nature (they stored a quantity), and they were all stored at the same subscript level (four subscripts) with similar subscripts (the third subscript was always text representing a color). However, they don't have to be. Data nodes may have a different number or type of subscripts, and they may contain different types of data.
Here’s an example of a more complex global with invoice data that has different types of data stored at different subscript levels:
invoice[invoice #,"Customer"] == Customer information invoice[invoice #,"Date"] == Invoice date invoice[invoice #,"Items"] == # of Items in the invoice invoice[invoice #,"Items",1,"Part"] == part number of 1st Item invoice[invoice #,"Items",1,"Quantity"] == quantity of 1st Item invoice[invoice #,"Items",1,"Price"] == price of 1st Item invoice[invoice #,"Items",2,"Part"] == part number of 2nd Item etc.
Often only a single data element is stored in a data node, such as a date or quantity, but sometimes it is useful to store multiple data elements together in a single data node. This is particularly useful when there is a set of related data that is often accessed together. It can also improve performance by requiring fewer accesses of the database.
For example, in the above invoice, each item included a part number, quantity, and price all stored as separate nodes, but they could be stored as a list of elements in a single node (the "info" node in this example), each separated by a colon:
invoice[invoice #,"Items",item #,"info"]=="part#:quantity:price"
A reference to the Globals database (a “global reference”) is essentially a reference to a multidimensional array.
As with multidimensional arrays, no declarations or definitions or reservations of storage are required to access or store data in the database; global data simply pops into existence as data is stored. The following example, shows the string "I'm a very good person" stored in a Global with two subscripts, "Smith" and "John"
person["Smith","John"]== "I'm a very good person"
The programmer has complete flexibility in how to structure these global data arrays.