在 Standard 或 Advanced 许可等级下可用。
关系类包含多种属性,这些属性可定义源中对象与目标中对象相关联的方法。 在创建关系类时指定这些属性。
- 类型:简单或复合
- 源类与目标类
- 主键与外键
- 基数:是一对一、一对多还是多对多的关系?
- 消息通知方向,适用于希望实施自定义级联更新或删除行为的情况
- 是否要为每种关系存储属性
- 名称
- 前向标注与后向标注,导航 ArcMap 中相关记录时显示
创建关系后,可以指定规则来优化基数。
简单与复合
在创建关系类时,指定是简单关系类还是复合关系类。
在简单关系中,相关对象可以彼此独立存在。 例如,在铁路网络中,可能存在拥有一个或多个相关信号灯的铁路交叉点。 但是,铁路交叉点上可以没有信号灯,并且存在信号灯的铁路网络上也可以没有铁路交叉点。
当删除简单关系中的源对象时,与匹配目标对象对应的外键字段值将设置为“空”。 此外键行为专用于保持要素间的引用完整性。 如果删除源要素,那么外键中的值不会再将该行与源中的要素相关联,因此,将不再需要外键值并将其设置为“空”。 外键的唯一用途就是维持目标对象与相关源对象间的关系。 如果不存在具有匹配主键值的源要素,则没有保留外键值的理由。 如果以后要将相同的目标要素与新的或不同的源要素相关联,则可将 FK 字段从“空”更新至新的 FK 值。
删除目标对象对相关源对象中的主键值不起任何作用。
简单关系可拥有一对一、一对多或多对多基数。
与简单关系相同,复合关系也可在删除对象时保持引用完整性,但它们是以不同的方式来执行此操作。 在复合关系中,目标对象无法独立于源对象存在,因此在删除源对象时,也会在此过程中删除相关的目标对象,这称为级联删除。
此依存规则也可通过 ArcMap 的“验证要素”命令来强制执行,该命令在编辑会话中运行,用以测试引用完整性。 如果创建了目标对象却未将其与源对象进行关联,“验证要素”将会发出存在错误的警告。
复合关系还有助于在空间上维护要素;在将消息发送设置为“向前”时,移动或旋转源要素会使相关目标要素随其一同移动或旋转。
复合关系在创建时始终为一对多的关系,但使用关系规则可以将其限制为一对一的关系。
源类与目标类
创建关系类时,选择一个类作为源类,选择另一个类作为目标类。 不要混淆这两种类至关重要。 在复合关系中采用级联删除行为的情况下,这种重要性显而易见。
在简单关系中,正确理解这一点至关重要。 这是因为当您删除源类中的记录时,简单关系类将在目标类中查找匹配记录,并将其键字段的值设置为 Null。 如果选择错误的类作为源并删除源中的对象,则会在外键字段中引入错误。 以下示例说明了此错误的发生过程:
情况 1:宗地至区域(错误)
这是一个常见的错误场景。 Zone 表包含对不同分区代码的描述,且在概念上类似于 ArcGIS Desktop Advanced Workstation 查找表。 在本例中,Parcel 类为源,Zone 表为目标。 这就是在 ArcGIS Desktop Advanced Workstation 中设置关系的方式。 问题是在删除宗地时,Zone 表中匹配记录的键字段 (Zone) 中的值设置为“空”,然后其他具有该分区代码的任何宗地在 Zone 表中不会具有匹配项。
情况 2:区域至宗地(正确)
要解决此问题,请将 Zone 表设置为源。 删除宗地(目标对象)时,对 Zone 表没有任何影响;删除“分区”代码(源对象)时,只会将匹配宗地记录中 Zone 字段的值设置为“空”,这一点与实际情况相符,因为它们在 Zone 表中不再有匹配的记录。
主键与外键
在关系类中,源中的对象通过其关键字段中的值匹配目标中的对象。 在下面的示例中,宗地 789 与许可 2 和许可 3 相匹配,因为所有这两个许可记录均具有相同的宗地 ID。
关系的源类中的键字段称为主键,通常缩写为 PK。 与真实的主键不一样,在关系的主键字段中的每个对象不需要具有唯一的值。
目标类中的键字段称为外键,通常缩写为 FK。 其中包含与源类中主键字段的值匹配的值。 此外,键字段的每一行不需要具有唯一的值。
键字段可能具有不同的名称,但必须具有相同的数据类型并且包含相同类型的信息,例如宗地 ID。 除了二进制大对象 (BLOB)、日期和栅格之外,所有数据类型的字段都可能是键字段。 并且可在创建关系类时指定键字段。
在确定主键字段时,可以选择使用行 ID 字段,通常称为 ObjectID 字段。 ObjectID 字段在创建要素类/表或者在注册企业级地理数据库图层/表时由 ArcGIS 自动添加。 此字段可确保每条记录具有唯一 ID。 该字段由 ArcGIS 维护,无法对其进行修改。
只要给定对象保留在其原始类中,则其 ObjectID 值永远都不会更改,并且如果该对象为要素,则不会对其进行分割。 如果对某个要素进行分割,则其将保留原始要素(但将更新几何)并创建一个新要素,将为该要素分配一个新的 ObjectID。 因此,只有具有原始 ObjectID 的要素才会保持由 ObjectID 值决定的所有关系。
因此,最好创建并使用您自己的主键字段,而不依赖于 ObjectID 字段。 如下内容描述了您自己的主键字段在执行每个操作时帮助维持关系的方式。
- 在将记录导入到其他要素类或表时,将指定新的 ObjectID 值,同时会丢失基于原始 ObjectID 值的所有关系。 相反,如果您将关系基于另一个主键,则在导入记录时,主键中的 ID 值将不会更改。 这样就可以在将相关对象集导入到新类时保留关系。
一个例外情况是当您使用复制/粘贴功能时。 复制/粘贴将保留 ObjectID 值,因此如果打算仅采用该方法移动对象,则可以使用 ObjectID 字段作为主键。
- 复制将 ObjectID 字段用作主键字段的关系类时,在同步过程中需要进行额外处理,这可能会影响性能。 在某些情况下,还可能导致意外行为。 有关在复制中使用 ObjectID 作为主键的详细信息,请参阅复制和相关数据。
- 在对某个要素进行分割时,原始要素将会保留(几何将进行更新),并创建一个新要素。 如果您的关系基于原始 ObjectID,则仅在分割中创建的两个要素之一将保持该关系。 但是,如果您使用了另一个字段作为键,则在分割要素时,会将原始要素的 ID 值复制到两个新要素。 因此,在理想情况下,如果将关系类设置为多对多,则相关表中的记录会立即与两个新要素相关联。
如果您不打算分割要素并且确定所有对象都将保留在其原始类中,则可以使用 ObjectID 作为其 ID。 如果无法对此作出保证,则最好建立并使用自己的 ID 字段,而不依赖于 ObjectID 字段。
- 在合并两个要素时,新的要素将保留其中一个原始要素的 ObjectID。 如果计划合并要素但却不想将要素从其类中移出或对要素进行分割,可以使用 ObjectID 字段作为主键。
基数
关系的基数指定可与目标类中对象数相关联的源类中的对象数。 关系可以拥有以下三种基数之一:
一对一 - 一个源对象仅可以与一个目标对象相关联。 例如,一个宗地只能具有一个法定描述。 在 ArcGIS 中,此基数也涵盖多对一。 多对一关系的示例之一就是许多个宗地与相同的法定描述相关联。
一对多 - 一个源对象可以与多个目标对象相关联。 例如,一个宗地可能具有许多建筑物。 在一对多关系中,“一”方必须为源类,“多”方必须为目标类。
多对多 - 一个源对象可以与多个目标对象相关联,相反,一个目标对象也可以与多个源对象相关联。 例如,一个给定的房产可能拥有许多个所有者,同时一个给定的所有者可能拥有许多房产。
术语“一”和“多”可能会产生误导。 “一”是真正的零对一,而“多”则是真正的零对多。 因此,当您创建宗地与建筑物间的一对多关系时,举例来说,该关系将允许下列所有情况:
- 不含建筑物的宗地
- 不含宗地的建筑物
- 具有任意数量建筑物的宗地
创建关系后,可以通过为关系设置规则来优化基数。 可以通过设置规则来指定允许与目标中多个对象相关联的源中的对象数。
关系规则
在创建关系类时,可使用一对一、一对多或多对多的基数对其进行创建。
关系通常需要使用更严格的术语来定义。 例如,在宗地和建筑物的关系中,您可能需要要求每个建筑物都与一个宗地相关联,或者一个宗地可以包含最大数量的建筑物。 要防止用户忘记将一个建筑物与一个宗地相关联,还要防止用户将过多的建筑物与一个宗地相关联。
如果具有子类型,则可以限制与目标中特定类型对象相关的源中对象的数量和类型。 例如,钢制电线杆支持 A 类变压器,而木杆可以支持 B 类变压器。 此外,您可能还需要为每个有效子类型对指定允许的基数范围。 例如,钢制电线杆支持 0 至 3 个 A 类变压器,而木杆可以支持 0 至 2 个 B 类变压器。
创建关系类后,可以指定有助于增强这些引用完整性规则的规则:
- 在 ArcCatalog 或“目录”窗口中,右键单击现有的关系类以显示其关系类属性对话框,然后单击规则选项卡。
- 从源类中选择一个子类型并从目标类中选中相应的子类型。
- 选中源基数以及目标基数的复选框。 为规则设置相应的最小和最大基数。 对话框会阻止您作出最小基数值大于最大基数值的设置,因此,先设置最大基数值。
将关系规则添加至关系类后,该规则将成为唯一可以存在的有效关系。 要使其他关系组合和基数有效,必须添加更多关系规则。
在以下示例中,HazMat 垃圾填埋场可能与一口或两口深井,或者两口到七口浅井相关。 但是,如果卫生垃圾填埋场与一口深井相关联,但却未在这两种子类型之间创建规则,则“验证要素”命令会将该关系视为无效。
设置规则并开始编辑后,可以使用 ArcMap“验证要素”命令对其进行测试。 “验证要素”命令将在任何当前所选的要素违反关系规则时发出通知。
消息通知方向
正如前文所述,在删除复合关系中的源对象时,相关联的目标对象会自动删除。
无论您使用的是简单关系还是复合关系,可能存在需要更新某一要素以触发其相关要素中更新的其他操作。 此外,在一个方向、另一个方向或两个方向上均可能需要更新。
- 当移动或旋转要素时,需要相关要素与其一起移动或旋转。
- 当更新要素时,需要相关要素中的属性自动更新。
- 更新源对象可要求相关目标对象进行更新。
- 更新目标对象可要求相关源对象进行更新。
如果您的关系需要此行为,当源对象及目标对象发生变化时,您可以让源对象及目标对象通过发送消息来相互通知,以便相关对象进行相应的更新。
为此,在创建关系时,需要设置消息通知方向。 如果更新源对象要求相关目标对象进行更新,请将消息通知方向设置为“向前”。 如果更新目标对象要求相关源对象进行更新,请将消息通知方向设置为“向后”。 如果您需要这两者,请将消息通知方向设置为“双向”。 创建关系后,您必须将该行为设置到接收消息的对象中,以便它们可以作出响应。
唯一的例外情况是当消息发送设置为“向前”时的复合关系。 如果创建具有向前消息发送的复合关系,则移动或旋转源对象将导致相关目标要素随之自动移动或旋转。 假如正确地建立了这种关系,那么在创建这种关系后此功能即可发挥作用,而无需额外的自定义程序设计。
对于其他消息通知方向,需要进行自定义编程。 除非您正在创建具有向前消息发送的复合关系或者打算对自定义行为进行编程,否则请将消息通知设置为“无”。 如若不然,每次执行编辑操作时都会生成不必要的消息,会导致性能降低。
在设置复合关系的方向时,请记住,当删除复合关系中的源对象时,将自动删除目标中的所有相关对象。 不管消息发送设置为“向前”、“向后”、“双向”还是“无”,都会发生这种情况。
方向 | 对简单关系的作用 | 对复合关系的作用 |
---|---|---|
向前 | 除非进行自定义程序设计,否则不起任何作用 |
|
向后 | 除非进行自定义程序设计,否则不起任何作用 |
|
双向 | 除非进行自定义程序设计,否则不起任何作用 |
|
无 | 阻止消息发送,可使性能略微提高 |
|
多对多关系
在一对一和一对多关系中,源类主键中的值会直接与目标类外键中的值相关联。
另一方面,多对多关系需要使用中间表来映射关联。 因此,当创建多对多关系时,将自动创建一个中间表。 中间表可将来自源的主键值映射至来自目标的外键值。 每一行都将一个源对象与一个目标对象相关联。
在创建中间表时,只会生成字段。 ArcGIS 无法得知哪些源对象与哪些目标对象相关联,因此在表中必须手动创建行。 填充此表是建立关系过程中最耗时的部分。
关系属性
多对多关系的中间表可以选择用于第二个目的:存储关系本身的属性。 例如,在宗地数据库中,宗地与所有者之间可能具有关系类,其中所有者拥有宗地,同时宗地归所有者所有。 每个关系的属性可以是所有权的百分比。 如果需要存储此类属性,可在创建关系时或以后的任何时间将其添加到中间表。
尽管不是那么有用,但是当您设置一对一或一对多关系时,您可能同样需要存储关系的属性。 如果是这种情况,则必须在创建关系时进行指定,以便创建一个中间表。 与多对多关系相同,中间表可将来自源的主键值映射至来自目标的外键值,以此来为每种关系存储任意数量的属性。
可以在 ArcCatalog 或“目录”窗口中预览中间表以查看其中包含的数据。 如果将关系类添加至 ArcMap,则其将显示为一个可以打开并进行操作的表。 ArcGIS 不会为其他操作公开中间表。 例如,无法在要添加或删除字段的 ArcCatalog 或“目录”窗口中显示其属性,并且不支持使用默认值或属性域。
名称
每种关系类都具有一个在目录树中显示的名称。 要使数据库结构易于理解,请以能够描述关系的名称对关系类命名。
以源要素类的名称开头,后跟 Has 或 Have,然后以目标要素类的名称结尾。 例如,AddressHasZones 或 ParcelsHaveOwners。 如果关系基数为多对一或多对多,则以复数形式表示源要素类名称,如果关系基数为一对多或多对多,则以复数形式表示目标要素类名称。
您可以使用此方法,根据关系类的名称确定其基数。 例如,ParcelsHaveOwners 的两个要素类均使用复数形式,可以想到它是多对多关系。
前向标注与后向标注
前向标注与后向标注在 ArcMap 中的属性及识别结果对话框中显示,有助于在相关对象间进行导航。
关系类具有如下两种标注:
- 在从源导航至目标时所显示的前向标注。 在杆式变压器示例中,该标注可显示为“支持”,这表示此杆支持这些变压器。
- 在从目标导航至源时所显示的后向标注。 在杆式变压器示例中,该标注可显示为“已安装”,这表示这些变压器安装在此电线杆上。