Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >多维存储的SQL和对象使用(一)

多维存储的SQL和对象使用(一)

作者头像
用户7741497
发布于 2022-06-09 03:04:47
发布于 2022-06-09 03:04:47
84800
代码可运行
举报
文章被收录于专栏:hml_知识记录hml_知识记录
运行总次数:0
代码可运行

多维存储的SQL和对象使用(一)

本章介绍InterSystems IRIS®对象和SQL引擎如何利用多维存储(全局变量)来存储持久对象、关系表和索引。

尽管InterSystems IRIS对象和SQL引擎会自动提供和管理数据存储结构,但了解其工作原理的详细信息还是很有用的。

数据的对象视图和关系视图使用的存储结构是相同的。为简单起见,本章仅从对象角度介绍存储。

数据

每个使用%Storage.Persistent存储类(默认)的持久化类都可以使用多维存储(全局变量)的一个或多个节点在InterSystems IRIS数据库中存储其自身的实例。

每个持久化类都有一个存储定义,用于定义其属性如何存储在全局变量节点中。这个存储定义(称为“默认结构”)由类编译器自动管理。

默认结构

用于存储持久对象的默认结构非常简单:

  • 数据存储在名称以完整类名(包括包名)开头的全局变量中。附加“D”以形成全局数据的名称,而附加“I”作为全局索引。
  • 每个实例的数据都存储在全局数据的单个节点中,所有非瞬态属性都放在$list结构中。
  • 数据全局变量中的每个节点都以对象ID值作为下标。默认情况下,对象ID值是通过调用存储在全局变量数据根(没有下标)的计数器节点上的$Increment函数提供的整数。

例如,假设我们定义了一个简单的持久化类MyApp.Person,它有两个文本属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class MyApp.Person Extends %Persistent
{
Property Name As %String;
Property Age As %Integer;
}

如果我们创建并保存此类的两个实例,得到的全局变量结果将类似于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ^MyApp.PersonD = 2  // counter node
 ^MyApp.PersonD(1) = $LB("",530,"Abraham")
 ^MyApp.PersonD(2) = $LB("",680,"Philip")

注意,存储在每个节点中的$List结构的第一部分是空的; 这是为类名保留的。 如果定义Person类的子类,则此槽包含子类名。 当多个对象存储在同一个区段内时,%OpenId方法(由%Persistent类提供)使用此信息多态地打开正确的对象类型。 此槽在类存储定义中显示为名为“%%CLASSNAME”的属性。

IDKEY

IDKEY机制允许显式定义用作对象ID的值。为此,只需将IDKEY索引定义添加到类中,并指定将提供ID值的一个或多个属性。请注意,一旦保存对象,其对象ID值就不能更改。这意味着在保存使用IDKEY机制的对象后,不能再修改该对象ID所基于的任何特性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class MyApp.Person Extends %Persistent
{
Index IDKEY On Name [ Idkey ];

Property Name As %String;
Property Age As %Integer;
}

如果我们创建并保存Person类的两个实例,得到的全局变量结果现在类似于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ^MyApp.PersonD("Abraham") = $LB("",530,"Abraham")
 ^MyApp.PersonD("Philip") = $LB("",680,"Philip")

请注意,不再定义任何计数器节点。还要注意,通过将对象ID基于Name属性,我们已经暗示了Name的值对于每个对象必须是唯一的。

如果IDKEY索引基于多个属性,则主数据节点具有多个下标。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class MyApp.Person Extends %Persistent
{
Index IDKEY On (Name,Age) [ Idkey ];

Property Name As %String;
Property Age As %Integer;
}

在这种情况下,生成的全局变量现在类似于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ^MyApp.PersonD("Abraham",530) = $LB("",530,"Abraham")
 ^MyApp.PersonD("Philip",680) = $LB("",680,"Philip")

重要提示:IDKEY索引使用的任何属性的值中都不能有连续的一对竖线(||),除非该属性是对持久类实例的有效引用。 这种限制是由InterSystems SQL机制的工作方式强加的。 IDKey属性中使用||会导致不可预知的行为。

Subclasses

默认情况下,持久性对象的子类引入的任何字段都存储在附加节点中。 子类的名称用作附加的下标值。

例如,假设我们定义了一个具有两个文本属性的简单持久MyApp.Person类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class MyApp.Person Extends %Persistent
{
Property Name As %String;

Property Age As %Integer;
}

现在,我们定义了一个持久子类MyApp.Students,它引入了两个额外的文本属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class MyApp.Student Extends Person
{
Property Major As %String;

Property GPA As %Double;
}

如果我们创建并保存此MyApp.Student类的两个实例,得到的全局结果将类似于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
^MyApp.PersonD = 2  // counter node
^MyApp.PersonD(1) = $LB("Student",19,"Jack")
^MyApp.PersonD(1,"Student") = $LB(3.2,"Physics")

^MyApp.PersonD(2) = $LB("Student",20,"Jill")
^MyApp.PersonD(2,"Student") = $LB(3.8,"Chemistry")

Person类继承的属性存储在主节点中,而由Student类引入的属性存储在另一个子节点中。这种结构确保了学生数据可以作为人员数据互换使用。例如,列出所有Person对象名称的SQL查询正确地获取PersonStudent数据。当属性被添加到超类或子类时,这种结构还使类编译器更容易维护数据兼容性。

请注意,主节点的第一部分包含字符串“Student”-它标识包含学生数据的节点。

父子关系

在父子关系中,子对象的实例存储为它们所属的父对象的子节点。这种结构确保子实例数据与父数据在物理上是集群的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/// An Invoice class
Class MyApp.Invoice Extends %Persistent
{
Property CustomerName As %String;

/// an Invoice has CHILDREN that are LineItems
Relationship Items As LineItem  [inverse = TheInvoice, cardinality = CHILDREN];
}

LineItem

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/// A LineItem class
Class MyApp.LineItem Extends %Persistent
{
Property Product As %String;
Property Quantity As %Integer;

/// a LineItem has a PARENT that is an Invoice
Relationship TheInvoice As Invoice [inverse = Items, cardinality = PARENT];
}

如果我们存储多个Invoice对象的实例,每个实例都有关联的LineItem对象,则得到的全局变量结果将类似于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
^MyApp.InvoiceD = 2  // invoice counter node
^MyApp.InvoiceD(1) = $LB("","Wiley Coyote")
^MyApp.InvoiceD(1,"Items",1) = $LB("","Rocket Roller Skates",2)
^MyApp.InvoiceD(1,"Items",2) = $LB("","Acme Magnet",1)

^MyApp.InvoiceD(2) = $LB("","Road Runner")
^MyApp.InvoiceD(2,"Items",1) = $LB("","Birdseed",30)

嵌入对象

存储嵌入对象的方法是先将它们转换为序列化状态(默认情况下是包含对象属性的$List结构),然后以与任何其他属性相同的方式存储此串行状态。

例如,假设我们定义了一个具有两个文字属性的简单串行(可嵌入)类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class MyApp.MyAddress Extends %SerialObject
{
Property City As %String;
Property State As %String;
}

现在,我们修改前面的示例以添加嵌入的Home Address属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class MyApp.MyClass Extends %Persistent
{
Property Name As %String;
Property Age As %Integer;
Property Home As MyAddress;
}

如果我们创建并保存此类的两个实例,则生成的全局变量相当于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ^MyApp.MyClassD = 2  // counter node
 ^MyApp.MyClassD(1) = $LB(530,"Abraham",$LB("UR","Mesopotamia"))
 ^MyApp.MyClassD(2) = $LB(680,"Philip",$LB("Bethsaida","Israel"))

通过将全局流的数据拆分成一系列块(每个块小于32K字节)并将这些块写入一系列顺序节点,全局流被存储在全局流中。文件流存储在外部文件中。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Storage关键字SqlRowIdProperty,SqlTableNumber,State,StreamLocation,Type
对于串行(嵌入式)类,此关键字指示使用哪个数据定义来定义对象的序列化状态(序列化时对象属性的排列方式)。这也是默认数据定义,默认结构生成器将向其添加未存储的属性。
用户7741497
2022/07/07
2970
多维存储的SQL和对象使用(二)
持久化类可以定义一个或多个索引;其他数据结构用于提高操作(如排序或条件搜索)的效率。InterSystems SQL在执行查询时使用这些索引。InterSystems IRIS对象和SQL在执行INSERT、UPDATE和DELETE操作时自动维护索引内的正确值。
用户7741497
2022/06/09
7510
定义和构建索引(一)
索引是由持久类维护的结构,InterSystems IRIS®数据平台可以使用它来优化查询和其他操作。
用户7741497
2022/06/07
6470
类关键字SqlTableName,StorageStrategy,System,ViewQuery
通常,当类名是SQL保留字(并不少见)或希望SQL表包含类名不支持的字符(如“_”字符)时,可以使用此关键字。
用户7741497
2022/07/06
3960
定义和构建索引(二)
与典型的SQL一样,InterSystems IRIS支持惟一键和主键的概念。 InterSystems IRIS还能够定义IdKey,它是类实例(表中的行)的唯一记录ID。 这些特性是通过Unique、PrimaryKey和IdKey关键字实现的:
用户7741497
2022/06/07
7160
SQL定义表(二)
InterSystems IRIS提供了两种方法来唯一标识表中的行:RowID和主键。
用户7741497
2022/06/06
1.6K0
使用多维存储(全局变量)(一)
在全局节点中存储数据很简单:像对待任何其他变量一样对待全局变量。 区别在于对全局变量的操作是自动写入数据库的。
用户7741497
2022/06/08
8350
SQL修改数据库
可以对现有的表使用SQL语句,也可以对相应的持久化类使用ObjectScript操作来修改InterSystems IRIS®数据平台数据库的内容。 不能修改定义为只读的持久类(表)。
用户7741497
2022/06/06
2.5K0
SQL查询数据库(二)
InterSystems SQL允许您在SQL查询中调用类方法。这为扩展SQL语法提供了强大的机制。
用户7741497
2022/06/06
2.4K0
使用多维存储(全局变量)(四)
InterSystems IRIS提供了使用全局变量实现完整事务处理所需的基本操作。 InterSystems IRIS对象和SQL自动利用这些特性。 如果直接将事务性数据写入全局变量,则可以使用这些操作。
用户7741497
2022/06/09
5790
定义和构建索引(三)
位图索引是一种特殊类型的索引,它使用一系列位串来表示与给定索引数据值相对应的一组ID值。
用户7741497
2022/06/07
1K0
关键字触发器定义,扩展数据块,类关键字Abstract,ClassType
触发器是在SQL中发生特定事件时执行的代码段。InterSystems IRIS支持基于执行INSERT、UPDATE和DELETE命令的触发器。根据触发器定义,指定的代码将在相关命令执行之前或之后立即执行。每个事件可以有多个触发器,只要它们被分配了执行顺序。
用户7741497
2022/07/06
8240
存储和使用流数据(BLOBs和CLOBs)
Intersystems SQL支持将流数据存储为Intersystems Iris ®DataPlatform数据库中的 BLOBs(二进制大对象)或 CLOBs(字符大对象)的功能。
用户7741497
2022/06/07
1.4K0
类关键字NoExtent,OdbcType,Owner,ProcedureBlock
如果该关键字为真,则该类没有 extent。不能创建此类的实例。通常,这样的类会扩展或覆盖从%Library.Persistent继承的标准持久接口。
用户7741497
2022/07/06
2850
SQL排序(一)
排序规则指定值的排序和比较方式,并且是InterSystems SQL和InterSystemsIRIS®数据平台对象的一部分。有两种基本排序规则:数字和字符串。
用户7741497
2022/06/06
1.5K0
重新定义读取器处理相关对象的方式
当%XML.Reader找到与启用了XML的类相关的XML元素时,读取器会调用该类的XMLNew()方法,后者又会在默认情况下调用%New()。也就是说,当读取器找到相关元素时,它会创建相关类的新对象。新对象由从XML文档读取的数据填充。
用户7741497
2022/07/05
4710
【设计模式】学习JS设计模式?先掌握面向对象!
一个模式就是一个可重用的方案,可应用于在软件设计中的常见问题,另一种解释就是一个我们如何解决问题的模板 - 那些可以在许多不同的情况里使用的模板。 --w3cschool
一尾流莺
2022/12/10
4620
将XML导入到对象中
注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码, IRIS将使用前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。
用户7741497
2022/07/04
1.8K0
SQL定义表(一)
可以通过定义表(使用CREATE TABLE)或通过定义投影到表的持久类来创建表:
用户7741497
2022/06/06
1.4K0
SQL定义表(三)
调用此方法时,它将尝试创建Sample.Employee表(以及相应的Sample.Employee类)。如果成功,则将SQLCODE变量设置为0。如果失败,则SQLCODE包含指示错误原因的SQL错误代码。
用户7741497
2022/06/06
1.3K0
相关推荐
Storage关键字SqlRowIdProperty,SqlTableNumber,State,StreamLocation,Type
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验