#关系表

0 关注者 · 8 帖子

关系模型将数据组织到一个或多个由列和行组成的(或“关系”)中,并用唯一的键标识每一行。行也称为记录或元组。

了解有关关系数据模型的更多信息。

InterSystems 数据平台 (IDP) 支持关系表,这是多模型存储概念的一部分。IDP 可提供对关系表的 SQL 和 API 访问。

文档

文章 Michael Lei · 八月 31, 2023 1m read

InterSystems 常见问题解答

通过在持久类(=table)定义中提供的%BuildIndices() 方法的参数中指定要重建索引的 ID 的开始值和结束值,您可以仅重建该范围内的索引。

例如,要仅针对 ID=10 到 20 重建 Sample.Person 类中的 NameIDX 索引和 ZipCode 索引,请执行以下代码(ID 范围在第 5 个和第 6 个参数中指定)。

set status = ##class (Sample.Person). %BuildIndices ( $LB ( "NameIDX" , "ZipCode" ), 1 ,, 1 , 10 , 20 )

$LB() 是$ListBuild() 函数。 %BuildIndices() 方法使用它来指定索引名称。

有关如何重建索引的更多信息,请参阅文档

2018.1版本请参考此文档

0
0 176
文章 Weiwei Gu · 八月 4, 2023 3m read

InterSystems IRIS 目前将类限制为 999 个属性。

但是,如果您需要为每个对象存储更多数据该怎么办?

本文将回答这个问题(附加了社区 Python 网关的客串以及如何将广泛的数据集传输到 Python 中)。

答案其实很简单 - InterSystems IRIS 目前将类限制为 999 个属性,但不限制 999 个基元(primitives)。 InterSystems IRIS 中的属性可以是具有 999 个属性的对象等等 - 该限制很容易被忽略。

0
0 176
文章 Lilian Huang · 九月 1, 2022 6m read

在我们开始谈论数据库和现有的不同数据模型之前,我们最好先谈谈什么是数据库以及如何使用它。

一个数据库是以电子方式存储和访问的有组织的数据集合。它用于存储和检索通常与主题或活动相关的结构化、半结构化或原始数据。
每个数据库的核心至少存在一个用于描述其数据的模型。并且根据它所基于的模型,一个数据库可能具有略微不同的特征并存储不同数据类型。

要写入、检索、修改、排序、转换或打印数据库中的信息,需要使用称为数据库管理系统 (DBMS) 的软件。

数据库及其各自的数据库管理系统的大小、容量和性能增加了几个数量级。各个领域的技术进步使之成为可能,例如处理器、计算机内存、计算机存储和计算机网络。一般来说,数据库技术的发展根据数据模型或结构分为四代:导航型、关系型、对象型和后关系型。

与以特定数据模型为特征的前三代不同,第四代包括许多基于不同模型的不同数据库。它们包括列、图、文档、组件、多维、键值、内存等。所有这些数据库都由一个单一的名称 NoSQL 联合起来(没有 SQL,或者现在更准确地说不仅仅是 SQL)。

而且,现在出现了一个新的类,叫做NewSQL这些是现代关系数据库,旨在为在线事务处理工作负载(读写)提供与 NoSQL 系统相同的可扩展性能,同时使用 SQL 和维护 ACID

0
0 387
文章 Weiwei Gu · 六月 27, 2022 6m read

Globals,这些存储数据的魔剑,已经存在了一段时间,但是没有多少人能够有效地使用它们,也没有多少人知道这个超级武器。

如果你把Globals的东西用在它们真正能发挥作用的地方,其结果可能是惊人的,要么是性能的提高,要么是整体解决方案的大幅简化 (1, 2).

Globals提供了一种特殊的存储和处理数据的方式,它与SQL表完全不同。它们在1966年首次出现在 M(UMPS)编程语言中, 该语言最初用于医学数据库。现在它仍然以同样的方式被使用,但也被其他一些以可靠性和高性能为首要任务的行业所采用:金融、交易等。

后来M(UMPS)演变为 Caché ObjectScript (COS). COS是由InterSystems公司开发的,作为M的一个超集. 其原始语言仍然被开发者社区所接受,并在一些实现中保持活力。在网络上有几个活跃的网址,比如:MUMPS Google group, Mumps User's group), effective ISO Standard等等

现代基于Globals的数据库支持交易、日志、复制、分区等。这意味着它们可以被用来构建现代的、可靠的、快速的分布式系统。

Gloabls并不将你限制于关系模型的范围内。它们让你可以自由地创建为特定任务优化的数据结构。对于许多应用来说,合理地使用好的Globals就如一颗真正的银子弹头,它所提供的速度是传统关系型应用的开发者所梦寐以求的。

作为一种存储数据的方法,globals可以在许多现代编程语言中使用,包括高级和低级语言。因此,本文将特别关注Globals本身,而不是它们曾经来自的语言。

1
1 323
文章 Nicky Zhu · 一月 11, 2021 3m read

当我向技术人员介绍InterSystems IRIS时,我一般会先讲其核心是一个多模型DBMS。

我认为这是其主要优势(在DBMS方面)。数据仅存储一次。您只需访问您想用的API。

  • 您想要数据的概要?用SQL!
  • 您想用一份记录做更多事情?用对象!
  • 想要访问或设置一个值,并且您知道键?用Globals!

乍一看挺好的,简明扼要,又传达了信息,但当人们真正开始使用InterSystems IRIS时,问题就来了。类、表和Globals是如何关联的?它们之间有什么关系?数据是如何存储的?

本文我将尝试回答这些问题,并解释这些到底是怎么回事。

第一部分 模型偏见

处理数据的人往往对他们使用的模型有偏见。

开发者们把数据视为对象。对他们而言,数据库和表都是通过CRUD(增查改删,最好是基于ORM)交互的盒子,但底层的概念模型都是对象(当然这对于我们大多数使用面向对象编程语言的开发者来说没错)。

而DBA大部分时间都在搞关系型DBMS,他们把数据视为表。对象只是行的封装器。

对于InterSystems IRIS,持久类也是一个表,将数据存储在Global中,因此需要进行一些澄清。

第二部分 举例

假设您创建了类Point:

Class try.Point Extends %Persistent [DDLAllowed]
{
    Property X;
    Property Y;
}

您也可以用DDL/SQL创建相同的类:

CREATE Table try.Point (
    X VARCHAR(50),
    Y VARCHAR(50))

编译后,新类将自动生成一个存储结构,将原生存储在Global中的数据映射到列(对于面向对象开发者而言,是属性):

Storage Default
{
<Data name="PointDefaultData">
    <Value name="1">
        <Value>%%CLASSNAME</Value>
    </Value>
    <Value name="2">
        <Value>X</Value>
    </Value>
    <Value name="3">
        <Value>Y</Value>
    </Value>
</Data>
<DataLocation>^try.PointD</DataLocation>
<DefaultData>PointDefaultData</DefaultData>
<IdLocation>^try.PointD</IdLocation>
<IndexLocation>^try.PointI</IndexLocation>
<StreamLocation>^try.PointS</StreamLocation>
<Type>%Library.CacheStorage</Type>
}

这是怎么回事?

自下向上(加粗文字很重要):

  • Type: 生成的存储类型,本例中是持久对象的默认存储
  • StreamLocation - 存储流的Global
  • IndexLocation - 索引Global
  • IdLocation - 存储ID自增计数器的Global
  • DefaultData - 存储将Global值映射到列/属性的XML元素
  • DataLocation - 存储数据的Global

现在我们的DefaultData是PointDefaultData,让我们分析下它的结构。本质上Global节点有这样的结构:

  • 1 - %%CLASSNAME
  • 2 - X
  • 3 - Y

所以我们可能期望我们的Global是这样的:

^try.PointD(id) = %%CLASSNAME, X, Y

但如果我们输出 Global 它会是空的,因为我们没有添加任何数据:

zw ^try.PointD

让我们添加一个对象:

set p = ##class(try.Point).%New()
set p.X = 1
set p.Y = 2
write p.%Save()

现在我们的Global变成了这样

zw ^try.PointD
^try.PointD=1
^try.PointD(1)=$lb("",1,2)

可以看到,我们期望的结构%%CLASSNAME, X, Y是用 $lb("",1,2) 设置的,它对应的是对象的X和Y属性(%%CLASSNAME 是系统属性,忽略)。

我们也可以用SQL添加一行:

INSERT INTO try.Point (X, Y) VALUES (3,4)

现在我们的Global变成了这样:

zw ^try.PointD
^try.PointD=2
^try.PointD(1)=$lb("",1,2)
^try.PointD(2)=$lb("",3,4)

所以我们通过对象或SQL添加的数据根据存储定义被存储在Global中(备注:可以通过在PointDefaultData 中替换X和Y来手动修改存储定义,看看新数据会怎样!)。

现在,如果我们想执行SQL查询会怎样?

SELECT * FROM try.Point

这段sql查询被转换为ObjectScript代码, 遍历^try.PointD,并根据存储定义(其中的 PointDefaultData 部分)填充列。

下面是修改。让我们从表中删除所有数据:

DELETE FROM try.Point

看看我们的Global变成什么样了:

zw ^try.PointD
^try.PointD=2

可以看到,只剩下ID计数器,所以新对象/行的ID=3。我们的类和表也继续存在。

但如果我们运行会怎样:

DROP TABLE try.Point

它会销毁表、类并删除Global。

zw ^try.PointD

看完这个例子,希望您现在对Global、类和表如何相互集成和互补有了更好的理解。根据实际需要选用正确的API会让开发更快、更敏捷、bug更少。

0
0 161