Globals can be accessed using a relational model, using an object model, or directly. For a video that explains the benefits of this multi-model access and a hands-on exercise that lets you try the three alternatives yourself, see Exploring Multiple Data Models with GlobalsOpens in a new tab.
What Are Globals?
One of the hallmarks of the InterSystems IRIS is its ability to store data once and allow you to access it using multiple paradigms. For example, you can use InterSystems SQL to visualize your data as rows and columns, or you can use ObjectScript and think of your data in terms of objects that have properties and methods. Your application can even mix these data models, using whichever model is easiest and more efficient for a given task. But no matter how you write or access your data, InterSystems IRIS stores it in underlying data structures known as globals.
Globals are persistent multidimensional sparse arrays:
Persistent — Globals are stored in the database and can be retrieved at any time, by any process that can access that database.
Multidimensional — The nodes in a global can have any number of subscripts. These subscripts can be integers, decimal numbers, or strings.
Sparse — Node subscripts do not have to be contiguous, meaning that subscripts without a stored value do not use any storage.
Nodes in a global can store many types of data, including:
Streams of character or binary data
Collections of data, such as lists or arrays
References to other storage locations
Even the server-side code you write is ultimately stored in globals!
Examples of Globals
If you’re new to InterSystems IRIS, you may be tempted to compare globals to data structures you have encountered from programming in other languages. This is a difficult exercise because a global is a flexible data structure that can be used in many different ways. But no matter the type of data it holds, a global is differentiated from a regular variable by placing a caret (^) in front of the name. This indicates that the variable is persisted to the database.
In its simplest form, a global can be used to store a single value, or scalar:
In this example, the global ^a holds an integer with the value 4, but as mentioned earlier, it can hold data of other types just as easily.
Globals can also be used as you would use an array in other languages, for example:
^month(1) = "January"
^month(2) = "February"
^month(3) = "March"
^month(4) = "April"
^month(12) = "December"
However, not every subscript in the array must include data. Since an array can be sparse, no storage is allocated for locations in an array that are not used.
^sparse(1,2,3) = 16
^sparse(1,2,5000) = 400
And, unlike arrays in many languages, the subscripts of a global can be negative numbers, real numbers, or strings. And the same array can hold data of varying types.
^misc(-4, "hello", 3.14) = 0
^misc("Sam", 27) = "Persimmon"
Because of their flexibility, many people conceptualize globals as dictionaries (or nested dictionaries), with key/value pairs. In the following example, the global ^team stores information about a baseball team:
^team("ballpark") = "Fenway Park"
^team("division") = "East"
^team("established") = 1901
^team("league") = "American"
^team("name") = "Boston Red Sox"
^team("retired number",1) = "Bobby Doerr"
^team("retired number",4) = "Joe Cronin"
^team("retired number",6) = "Johnny Pesky"
^team("retired number",8) = "Carl Yastrzemski"
^team("retired number",9) = "Ted Williams"
^team("world series titles") = $lb(1903,1912,1915,1916,1918,2004,2007,2013,2018)
In many languages, dictionaries are unordered, meaning that when you retrieve data from the dictionary, the data can be returned in some unspecified order. With globals, however, data is sorted according to its subscripts as it is stored.
It is more accurate to visualize a global as an ordered tree, where each node in the tree can have a value and/or children. In this regard, it is more flexible than nested dictionaries in other languages, where typically only the leaves of the tree contain data. In the following example, the global ^bird stores birds according to their scientific names, with the names of each bird stored at the leaves of the tree. Here, the root node stores an overall description of the global, while a node representing a family of birds stores a description of that family:
^bird = "Birds of North America"
^bird("Anatidae") = "Ducks, Geese and Swans"
^bird("Anatidae", "Aix", "sponsa") = "Wood Duck"
^bird("Anatidae", "Anas", "rubripes") = "American Black Duck"
^bird("Anatidae", "Branta", "leucopsis") = "Barnacle Goose"
^bird("Odontophoridae") = "New World Quails"
^bird("Odontophoridae", "Callipepia", "californica") = "California Quail"
^bird("Odontophoridae", "Callipepia", "gambelii") = "Gambel's Quail"
For an animated illustration of how data is stored in ordered trees, see Ordered Trees.
For a short hands-on exercise and a whiteboard demonstration on globals, see Globals QuickstartOpens in a new tab.