我们将从附录B- SAP HANA图参考文档的希腊神话图示例中获取脚本,以用于通常的SAP HANA平台,该平台已在数据中心本地部署。该示例的主要目的是展示SAP HANA的分析功能,展示如何使用图形算法分析对象和事件之间的关系。我们不会详细介绍该技术,从进一步的介绍中可以清楚地看出主要思想。有兴趣的人可以体验SAP HANA Express版本的功能自行解决,也可以免费学习使用SAP HANA Graph分析关联数据。
让我们将数据放入SAP HANA Cloud关系云中,看看分析希腊英雄的家族联系的可能性。记住,在“古希腊神话和传说”中有很多人物,到中间,你不记得谁是谁的儿子和兄弟?在这里,我们将为自己做一个备忘录,我们将永远不会忘记它。
首先,让我们创建一个SAP HANA Cloud实例。这很简单,您需要填写将来系统的参数,并等待几分钟,以便为您部署实例(图1)。
图1
因此,我们单击Create Instance按钮,然后将看到创建向导的第一页,在该页面上,我们需要指示实例的简称,设置密码并给出描述(图2)。
图2
我们单击“步骤2”按钮,现在我们的任务是指定未来SAP HANA实例的参数。在这里,您只能设置将来系统的RAM大小,所有其他参数将自动确定(图3)。
图3
我们看到现在我们有机会选择最小值30GB和最大值900GB。我们选择30GB,并自动确定在此内存量下,需要两个虚拟处理器来支持计算,而需要120GB来在磁盘上存储数据。由于我们可以使用SAP HANA本机存储扩展(NSE)技术,因此在此处分配了更多空间。如果选择较大的内存大小(例如255GB),则将需要17个虚拟处理器和720GB磁盘内存(图4)。
图4
但是我们不需要太多的内存作为示例。我们将参数恢复为原始值,然后单击“步骤3”。现在,我们必须选择是否使用数据湖。答案对我们来说是显而易见的。当然可以。这是我们要进行的实验(图5)。
图5
在这一步,我们拥有创建数据湖实例的更多功能和自由。您可以选择所需计算资源和磁盘存储的大小。使用的组件/节点的参数将自动选择。系统本身将确定“协调器”和“工作”节点的必要计算资源。如果您想了解有关这些组件的更多信息,最好转向SAP IQ资源和SAP HANA Cloud数据湖。然后继续,单击“步骤4”。
图6
在此步骤中,我们将确定或限制可以访问SAP HANA未来实例的IP地址。如您所见,这是向导的最后一步(图6),仍然需要单击Create Instance并为自己倒咖啡。
图7
该过程已经开始(图7),不需要花费很多时间,尽管晚上很晚,我们还是有时间喝浓咖啡。还有什么时候您可以冷静地尝试该系统并拧紧不同的芯片?这样就创建了我们的系统(图8)。
图8
我们有两个选项:打开SAP HANA Cockpit或SAP HANA数据库浏览器。我们知道有可能从Cockpit推出第二个产品。因此,我们同时打开SAP HANA主控室,然后查看其中的内容。但是首先,您需要指定用户及其密码。请注意,SYSTEM用户不可用;您必须使用DBADMIN。在这种情况下,请指定在创建实例时设置的密码,如图9所示。
图9
我们去了Cockpit,我们看到了传统的SAP界面,以图块的形式显示,每个图块各自负责自己的任务。在右上角,我们看到一个指向SQL Console的链接(图10)。
图10
是她允许我们进入SAP HANA数据库浏览器。
该工具的界面类似于SAP Web IDE,但仅用于处理数据库对象。首先,当然,我们对如何进入数据湖很感兴趣。毕竟,现在我们已经打开了用于HANA的工具。让我们转到导航器中的“远程源”项,并查看到湖泊的链接(SYSRDL,RDL-Relation Data Lake)。这是所需的访问权限(图11)。
图11
继续,我们不必在管理员下工作。我们需要创建一个测试用户,在该用户下我们将使用HANA图形引擎进行实验,但是将数据放置在关系数据湖中。
脚本:
CREATE USER tstuser PASSWORD Password1 NO FORCE_FIRST_PASSWORD_CHANGE SET USERGROUP DEFAULT;
我们计划使用数据湖,因此必须授予权限,例如HANA_SYSRDL#CG_ADMIN_ROLE,以便您可以自由创建对象,执行我们想做的任何事情。
脚本:
GRANT HANA_SYSRDL#CG_ADMIN_ROLE TO tstuser;
现在,SAP HANA管理员下的工作已完成,SAP HANA数据库浏览器可以关闭,我们需要在创建的新用户tstuser下登录。为简单起见,请返回SAP HANA Cockpit并结束管理员会话。为此,在左上角有一个链接“清除凭据”(图12)。
图12
单击它之后,我们需要再次登录,但是现在在用户tstuser下(图13)。
图13
而且我们可以再次打开SQL控制台以返回SAP HANA数据库浏览器,但是要有一个新用户(图14)。
图14
脚本:
SELECT SESSION_USER, CURRENT_SCHEMA FROM DUMMY;
就是这样,现在我们确定我们可以在合适的用户下使用HANA。是时候在数据湖中创建表了。为此,有一个特殊的过程SYSRDL#CG.REMOTE_EXECUTE,您需要在其中传递一个参数-line = command。使用此功能,我们在数据湖中创建了一个表(图15),该表将存储我们的所有角色:英雄,希腊众神和泰坦。
图15
脚本:
CALL SYSRDL#CG.REMOTE_EXECUTE ('
BEGIN
CREATE TABLE "MEMBERS" (
"NAME" VARCHAR(100) PRIMARY KEY,
"TYPE" VARCHAR(100),
"RESIDENCE" VARCHAR(100)
);
END');
然后,我们创建一个表,在其中将保留这些角色的家庭联系(图16)。
图16
脚本:
CALL SYSRDL#CG.REMOTE_EXECUTE ('
BEGIN
CREATE TABLE "RELATIONSHIPS" (
"KEY" INTEGER UNIQUE NOT NULL,
"SOURCE" VARCHAR(100) NOT NULL,
"TARGET" VARCHAR(100) NOT NULL,
"TYPE" VARCHAR(100),
FOREIGN KEY RELATION_SOURCE ("SOURCE") references "MEMBERS"("NAME") ON UPDATE RESTRICT ON DELETE RESTRICT,
FOREIGN KEY RELATION_TARGET ("TARGET") references "MEMBERS"("NAME") ON UPDATE RESTRICT ON DELETE RESTRICT
);
END');
现在我们不会处理集成问题,这是一个独立的故事。原始示例包含用于创建希腊众神及其亲属关系的INSERT命令。我们使用这些命令。我们只需要记住,我们正在将命令通过过程传递给数据湖,因此我们需要将双引号加倍,如图17所示。
图17
脚本:
CALL SYSRDL#CG.REMOTE_EXECUTE ('
BEGIN
INSERT INTO "MEMBERS"("NAME", "TYPE")
VALUES (''Chaos'', ''primordial deity'');
INSERT INTO "MEMBERS"("NAME", "TYPE")
VALUES (''Gaia'', ''primordial deity'');
INSERT INTO "MEMBERS"("NAME", "TYPE")
VALUES (''Uranus'', ''primordial deity'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Rhea'', ''titan'', ''Tartarus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Cronus'', ''titan'', ''Tartarus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Zeus'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Poseidon'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Hades'', ''god'', ''Underworld'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Hera'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Demeter'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Athena'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Ares'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Aphrodite'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Hephaestus'', ''god'', ''Olympus'');
INSERT INTO "MEMBERS"("NAME", "TYPE", "RESIDENCE")
VALUES (''Persephone'', ''god'', ''Underworld'');
END');
第二张表(图18)
图18
脚本:
CALL SYSRDL#CG.REMOTE_EXECUTE ('
BEGIN
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (1, ''Chaos'', ''Gaia'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (2, ''Gaia'', ''Uranus'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (3, ''Gaia'', ''Cronus'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (4, ''Uranus'', ''Cronus'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (5, ''Gaia'', ''Rhea'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (6, ''Uranus'', ''Rhea'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (7, ''Cronus'', ''Zeus'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (8, ''Rhea'', ''Zeus'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (9, ''Cronus'', ''Hera'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (10, ''Rhea'', ''Hera'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (11, ''Cronus'', ''Demeter'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (12, ''Rhea'', ''Demeter'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (13, ''Cronus'', ''Poseidon'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (14, ''Rhea'', ''Poseidon'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (15, ''Cronus'', ''Hades'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (16, ''Rhea'', ''Hades'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (17, ''Zeus'', ''Athena'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (18, ''Zeus'', ''Ares'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (19, ''Hera'', ''Ares'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (20, ''Uranus'', ''Aphrodite'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (21, ''Zeus'', ''Hephaestus'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (22, ''Hera'', ''Hephaestus'', ''hasSon'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (23, ''Zeus'', ''Persephone'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (24, ''Demeter'', ''Persephone'', ''hasDaughter'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (25, ''Zeus'', ''Hera'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (26, ''Hera'', ''Zeus'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (27, ''Hades'', ''Persephone'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (28, ''Persephone'', ''Hades'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (29, ''Aphrodite'', ''Hephaestus'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (30, ''Hephaestus'', ''Aphrodite'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (31, ''Cronus'', ''Rhea'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (32, ''Rhea'', ''Cronus'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (33, ''Uranus'', ''Gaia'', ''marriedTo'');
INSERT INTO "RELATIONSHIPS"("KEY", "SOURCE", "TARGET", "TYPE")
VALUES (34, ''Gaia'', ''Uranus'', ''marriedTo'');
END');
现在,让我们再次打开“远程源”。基于对数据湖中表的描述,我们需要在HANA中创建虚拟表(图19)。
图19
我们找到两个表,在表对面设置“复选框”,然后单击Create Virtual Object(s)按钮,如图20所示。
图20
我们可以指定在其中创建虚拟表的模式。在这里,您需要指定前缀以使这些表更易于查找。之后,我们可以在导航器中选择Table,查看我们的表并查看数据(图21)。
图21
在此步骤中,请务必注意左下方的过滤器。应该有我们的用户名或我们的TSTUSER模式。
您快完成了。我们在湖中创建了表并将数据加载到其中,并且要从HANA级别访问它们,我们有虚拟表。我们准备创建一个新对象-图形(图22)。
图22
脚本:
CREATE GRAPH WORKSPACE "GREEK_MYTHOLOGY"
EDGE TABLE "TSTUSER"."RDL_RELATIONSHIPS"
SOURCE COLUMN "SOURCE"
TARGET COLUMN "TARGET"
KEY COLUMN "KEY"
VERTEX TABLE "TSTUSER"."RDL_MEMBERS"
KEY COLUMN "NAME";
一切正常,图表已准备就绪。您可以立即尝试对图形数据进行一些简单的查询,例如,找到混沌的所有女儿以及这些女儿的所有女儿。为此,图形分析语言Cypher将为我们提供帮助。它是专门为处理图形而创建的,方便,简单并有助于解决复杂问题。我们只需要记住,Cypher脚本需要使用表函数包装在SQL查询中。了解如何用这种语言解决我们的任务(图23)。
图23
脚本:
SELECT * FROM OPENCYPHER_TABLE( GRAPH WORKSPACE "GREEK_MYTHOLOGY" QUERY
'
MATCH p = (a)-[*1..2]->(b)
WHERE a.NAME = ''Chaos'' AND ALL(e IN RELATIONSHIPS(p) WHERE e.TYPE=''hasDaughter'')
RETURN b.NAME AS Name
ORDER BY b.NAME
'
)
让我们检查可视化SAP HANA图形分析工具的工作方式。为此,请在导航器中选择“图形工作区”(图24)。
图24
现在您可以看到我们的图表(图25)。
图25
您将看到一个已经着色的图形。我们使用屏幕右侧的设置进行了此操作。在左上角,显示了有关当前选定节点的详细信息。
好吧...我们做到了。数据位于数据湖中,我们使用SAP HANA中的工具对其进行分析。一种技术计算数据,另一种负责存储数据。在处理图形数据时,将从数据湖中请求图形数据并将其传输到SAP HANA。我们可以加快查询速度吗?如何确保数据存储在RAM中并且没有从数据湖加载?有一个简单但不是很好的方法-创建一个表以将数据湖表的内容加载到其中(图26)。
图26
脚本:
CREATE COLUMN TABLE MEMBERS AS (SELECT * FROM "TSTUSER"."RDL_MEMBERS")
但是还有另一种方式-这是在SAP HANA RAM中使用数据复制。与使用虚拟表访问存储在数据湖中的数据相比,这可以为SQL查询提供更好的性能。您可以在虚拟表和复制表之间切换。为此,将副本表添加到虚拟表。这可以使用ALTER VIRTUAL TABLE语句完成。之后,使用虚拟表的查询会自动访问位于SAP HANA RAM中的副本表。让我们看看如何做到这一点,让我们进行实验。我们执行这样的请求(图27)。
图27
脚本:
SELECT R.KEY, R.SOURCE, R.TYPE
FROM "TSTUSER"."RDL_RELATIONSHIPS" R inner join "TSTUSER"."MEMBERS" M on R.SOURCE=M.NAME
让我们看一下完成此请求所花的时间(图28)。
图28
我们花了92毫秒。让我们打开复制机制。为此,您需要创建虚拟表的ALTER VIRTUAL TABLE,然后将Lake数据复制到SAP HANA RAM。
脚本:
ALTER VIRTUAL TABLE "RDL_RELATIONSHIPS" ADD SHARED SNAPSHOT REPLICA COLUMN LOADABLE;
让我们检查执行时间,
如图29所示。图29
得到了7毫秒。这是一个很好的结果!我们只需花费很少的精力,即可将数据移至RAM。此外,如果您已经完成分析并且对性能满意,则可以再次关闭复制(图30)。
图30
脚本:
ALTER VIRTUAL TABLE "RDL_RELATIONSHIPS" DROP REPLICA;
现在,仅根据请求再次从Lake下载数据,并且SAP HANA RAM免费用于新任务。在我看来,今天,我们做了一件有趣的工作,并测试了SAP HANA Cloud的速度,便捷的单个数据访问点组织。该产品将继续发展,我们预计在不久的将来将直接连接到数据湖。这项新功能将能够更快地下载大量信息,消除不必要的开销,并改善特定于数据湖的操作的性能。我们将使用SAP IQ技术直接在数据云中创建和执行存储过程,也就是说,我们将能够在数据本身所在的位置应用处理和业务逻辑。
SAP CIS高级业务架构师Alexander Tarasov