写在前面
为了与大家保持一个愉快的沟通,以及便于描述方便,本文做了一些术语简写,如下:
Globals
: 全局变量1. Globals 概念
InterSystems IRIS®
的核心功能之一是其多维存储引擎
。此功能允许应用程序将数据存储在紧凑、高效、多维稀疏数组
中。这些数组称为全局数组
。
global
是一个可以存储任何类型数据的带下标变量。数据存储在磁盘上,可跨进程全局可用,因此得名“global
”。全局变量通过在名称前面放置上箭头符号 (^
) 来区分常规变量。
人们通常将 globals
称为稀疏的多维数组,因为它们具有类似数组的语法。注意:并非数组中的每个下标都必须包含数据
,例如:
^a(1,2,3) = 4
^a(1,2,5000) = 4
与许多语言中的数组不同,全局变量的下标可以是负数、实数或字符串
,例如:
^b(-4, "hello", 3.14) = 4
出于这个原因,许多人将globals
概念化为具有键/值对的字典或嵌套字典。
在许多语言中,字典是无序的,这意味着当您从字典中检索数据时,可以按某种未指定的顺序返回数据。但是,对于globals,数据在存储时会根据其下标进行排序
。
将 global视化为有序树更准确
,其中树中的每个节点都可以具有值和/或子级。在这方面,它比嵌套字典模型更灵活,嵌套字典模型通常只有树的叶子包含数据。
在下面的示例中,根节点存储全局的描述,而表示一个鸟类家族的节点存储该家族的描述:
^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"
2. Globals 特点
globals
提供了一种易于使用的方法,用于在持久的多维数组中存储数据。
例如,您可以使用名为 ^Settings
的全局变量将值“Red
”与键“Color
”相关联:
SET ^Settings("Color")="Red"
您可以利用globals
的多维特性来定义更复杂的结构:
SET ^Settings("Auto1","Properties","Color") = "Red"
SET ^Settings("Auto1","Properties","Model") = "SUV"
SET ^Settings("Auto2","Owner") = "Mo"
SET ^Settings("Auto2","Properties","Color") = "Green"
globals
具有以下特点:
易于使用 — 全局变量与其他编程语言变量一样易于使用。
多维 — 您可以使用任意数量的下标指定全局中节点的地址。例如,在 ^Settings(“Auto2”,“Properties”,“Color”)
中,下标 Color
是“Settings
”全局变量中的第三级节点。下标可以是整数、数字或字符串值,并且不必是连续的
。
稀疏 — 用于寻址全局节点的下标高度紧凑,不需要具有连续值
。
高效 — 全局变量上的操作 — 插入、更新、删除、遍历和检索 — 都经过高度优化,可实现最高的性能和并发性。还有其他用于专用操作的命令(如批量插入数据)。有一组特殊的全局变量是为临时数据结构
(如用于对记录进行排序)而设计的。
可靠 — InterSystems IRIS
数据库提供了许多机制来确保存储在全局变量中的数据的可靠性,包括逻辑级和物理级日志。执行数据库备份操作时,将备份存储在全局变量中的数据。
分布式 — InterSystems IRIS
提供了多种方法来控制存储在全局变量中的数据的物理位置。您可以定义用于存储全局数据库的物理数据库,或将全局数据库的一部分分布在多个数据库之间。使用 InterSystems IRIS
的分布式数据库功能,您可以在数据库和应用程序服务器系统网络之间共享全局变量。此外,通过镜像技术,存储在一个系统上的全局变量中的数据可以自动复制到另一个系统上。
并发 — 全局支持多个进程之间的并发访问。在单个节点(数组元素)中设置和检索值始终是原子的:无需锁定即可保证可靠的并发访问。此外,InterSystems IRIS
支持一组功能强大的锁定操作,可用于为涉及多个节点的更复杂案例提供并发性。使用对象或 SQL
访问时,将自动处理此并发。
事务性 — InterSystems IRIS
提供定义事务边界的命令;您可以启动、提交或回滚事务。在回滚的情况下,对事务中的全局变量所做的所有修改都将被撤消;数据库的内容将还原到其事务前状态。通过将各种 InterSystems IRIS 锁定操作与事务结合使用,您可以使用全局变量执行传统的 ACID 事务。(ACID 事务提供原子性、一致性、隔离性和持久性。使用对象或 SQL 访问时,会自动处理事务
。
本文档中描述的globals
不应与另一种类型的 InterSystems IRIS 数组变量混淆:进程专用全局变量
。
进程专用全局变量不是持久的
;它们仅在创建它们的进程期间持续存在。进程专用全局变量也不是并发的
;它们只能由创建它们的进程访问。^||
或 ^|"^"|
.例如:^||ProcessGlobal("Test")
与 ^|"^"|ProcessGlobal("Test")
是等价的
s ^||ProcessGlobal("Test")=2
s ^|"^"|ProcessGlobal("Test")=2
3. 案例
一个简单的例子可以演示全局变量的易用性和性能。下面的程序示例创建一个 10,000 节点的数组(如果存在,请先将其删除)并将其存储在数据库中。您可以尝试此操作来了解globals
的性能:
Set start = $ZH // get current time
Kill ^Test.Global
For i = 1:1:10000 {
Set ^Test.Global(i) = i
}
Set elap = $ZH - start // get elapsed time
Write "Time (seconds): ",elap // .0022771
我们还可以看到迭代和读取数组中的值需要多长时间(确保首先运行上面的示例来构建数组):
Set start = $ZH // get current time
Set total = 0
Set count = 0
// get key and value for first node
Set i = $Order(^Test.Global(""),1,data)
While (i '= "") {
Set count = count + 1
Set total = total + data
// get key and value for next node
Set i = $Order(^Test.Global(i),1,data)
}
Set elap = $ZH - start // get elapsed time
Write "Nodes: ",count,!
Write "Total: ",total,!
Write "Time (seconds): ",elap,!
输出
Time (seconds): .002171
Nodes: 10000
Total: 50005000
Time (seconds): .002272
4. 应用场景
在InterSystems IRIS
应用程序中,全局变量以多种方式使用,包括:
作为对象和 SQL
引擎共享的基础存储机制。
作为用于为对象和 SQL
数据提供各种索引(包括位图索引)的机制。
作为工作空间,用于执行某些可能不适合进程内存的操作。例如,当没有预先存在的索引可用于此目的时,SQL
引擎使用临时全局变量对数据进行排序。
用于对难以或低效表示为对象或 SQL 访问的持久性对象或 SQL 表执行专用操作。例如,可以定义一种方法(或存储过程或 Web 方法)来对表中保存的数据执行专门的分析。通过使用方法,这样的操作是完全封装的;调用方只需调用该方法。
实现特定于应用程序的自定义存储结构。许多应用程序都需要存储难以以关系方式表示的数据。使用globals
,您可以定义自定义结构,并通过对象方法将其提供给外部客户端。
用于 InterSystems IRIS
系统使用的各种特殊用途的数据结构,例如配置数据、类定义、错误消息和可执行代码。
Globals
不受关系模型限制。它们提供了开发针对特定应用优化的定制结构的自由。对于许多应用程序而言,明智地使用globals
可能是提供关系应用程序开发人员梦寐以求的性能的秘密武器。
无论您的应用程序是否直接使用globals
,了解它们的操作都很有用。了解globals
及其功能将帮助您设计更高效的应用程序,并帮助您确定应用程序的最佳部署配置。