持久化类可以定义一个或多个索引;其他数据结构用于提高操作(如排序或条件搜索)的效率。InterSystems SQL在执行查询时使用这些索引。InterSystems IRIS对象和SQL在执行INSERT
、UPDATE
和DELETE
操作时自动维护索引内的正确值。
标准索引将一个或多个属性值的有序集与包含属性的对象的对象ID
值相关联。
例如,假设我们定义了一个简单的持久化MyApp.Person
类,该类具有两个文本属性和一个关于其Name
属性的索引:
Class MyApp.Person Extends %Persistent
{
Index NameIdx On Name;
Property Name As %String;
Property Age As %Integer;
}
如果我们创建并保存此Person
类的多个实例,则生成的数据和索引全局变量类似于:
// data global
^MyApp.PersonD = 3 // counter node
^MyApp.PersonD(1) = $LB("",34,"Jones")
^MyApp.PersonD(2) = $LB("",22,"Smith")
^MyApp.PersonD(3) = $LB("",45,"Jones")
// index global
^MyApp.PersonI("NameIdx"," JONES",1) = ""
^MyApp.PersonI("NameIdx"," JONES",3) = ""
^MyApp.PersonI("NameIdx"," SMITH",2) = ""
请注意有关全局索引的以下事项:
“i”
(表示索引)的类名。SQLUPPER
排序函数对数据进行排序。这会将所有字符转换为大写(不考虑大小写进行排序),并在前面加上一个空格字符(强制所有数据作为字符串进行排序)。该索引包含足够的信息来满足许多查询,比如按姓名列出所有Person
类。
位图索引类似于标准索引,不同之处在于它使用一系列位字符串来存储与索引值对应的一组对象ID
值。
位字符串是一个包含一组特殊压缩格式的位(0
和1
值)的字符串。
InterSystems IRIS包含一组有效创建和使用位字符串的函数。
这些都列在下表中:
位操作
函数 | 描述 |
---|---|
$Bit | 在位串中设置或获取位。 |
$BitCount | 计算位串中的位数。 |
$BitFind | 查找位串中下一个出现的位。 |
$BitLogic | 对两个或多个位串执行逻辑(AND, OR)操作。 |
在位图索引中,位字符串中的顺序位置对应于索引表中的行(对象ID
号)。
对于给定值,位图索引维护一个位字符串,在给定值存在的每一行中包含1
,在没有给定值的每一行中包含0
。
请注意,位图索引只适用于使用系统分配的默认存储结构的对象,数值型对象ID
值。
例如,假设我们有一个类似如下的表:
ID | State | Product |
---|---|---|
1 | MA | Hat |
2 | NY | Hat |
3 | NY | Chair |
4 | MA | Chair |
5 | MA | Hat |
如果State
和Product
列有位图索引,则它们包含以下值:
State
列上的位图索引包含以下位字符串值:
MA 1 0 0 1 1
NY 0 1 1 0 0
注意,对于值“MA”
,在与State
等于“MA”
的表行对应的位置(1、4和5)中有一个1。
类似地,Product
列上的位图索引包含以下位字符串值(注意,这些值在索引中被排序为大写):
CHAIR 0 0 1 1 0
HAT 1 1 0 0 1
InterSystems SQL Engine可以通过对这些索引维护的位串进行迭代、计算位内位数或执行逻辑组合(AND, or
)来执行许多操作。
例如,要找到State
等于“MA”
、Product
等于“HAT”
的所有行,SQL引擎可以简单地将适当的位串与逻辑and
组合在一起。
除了这些索引之外,系统还维护一个额外的索引,称为“区段索引”,对于存在的每一行包含1,对于不存在的行(如已删除的行)包含0。 这用于某些操作,如否定。
位图索引将一个或多个属性值的有序集合与一个或多个包含与属性值对应的对象ID
值的位字符串相关联。
例如,假设我们定义了一个简单的持久MyApp
。
Person
类具有两个文字属性和Age
属性上的位图索引:
Class MyApp.Person Extends %Persistent
{
Index AgeIdx On Age [Type = bitmap];
Property Name As %String;
Property Age As %Integer;
}
如果我们创建并保存这个Person
类的几个实例,得到的数据和索引全局变量类似于:
// data global
^MyApp.PersonD = 3 // counter node
^MyApp.PersonD(1) = $LB("",34,"Jones")
^MyApp.PersonD(2) = $LB("",34,"Smith")
^MyApp.PersonD(3) = $LB("",45,"Jones")
// index global
^MyApp.PersonI("AgeIdx",34,1) = 110...
^MyApp.PersonI("AgeIdx",45,1) = 001...
// extent index global
^MyApp.PersonI("$Person",1) = 111...
^MyApp.PersonI("$Person",2) = 111...
关于全局索引,请注意以下几点:
“I”
(表示Index
)。64000
行的信息。这些位串中的每一个都被称为块。另请注意:因为该表有一个位图索引,所以会自动维护一个区索引。该盘区索引存储在索引GLOBAL
中,并使用前缀有“$”
字符的类名作为其第一个下标。
下面的示例使用类区索引来计算存储的对象实例(行)的总数。注意,它使用$ORDER
来迭代区索引的块(每个块包含大约64000行的信息):
ClassMethod Count1() As %Integer
{
New total,chunk,data
Set total = 0
Set chunk = $Order(^Sample.PersonI("$Person",""),1,data)
While (chunk '= "") {
Set total = total + $bitcount(data,1)
Set chunk = $Order(^Sample.PersonI("$Person",chunk),1,data)
}
Quit total
}
DHC-APP>w ##class(PHA.TEST.SQL).Count1()
208
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。