2019-12-19 13:17:53 -08:00
|
|
|
|
# What is a relationship?
|
2019-12-18 18:57:18 -08:00
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
A relationship is a named associate between exactly two [entities](entity.md), a source and a destination.
|
2019-12-18 18:57:18 -08:00
|
|
|
|
|
2023-08-26 06:10:13 +09:00
|
|
|
|
<p align="center">
|
|
|
|
|
<img width="70%" src="https://raw.githubusercontent.com/datahub-project/static-assets/main/imgs/metadata-modeling.png"/>
|
|
|
|
|
</p>
|
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
From the above graph, a `Group` entity can be linked to a `User` entity via a `HasMember` relationship.
|
|
|
|
|
Note that the name of the relationship reflects the direction, i.e. pointing from `Group` to `User`.
|
|
|
|
|
This is due to the fact that the actual metadata aspect holding this information is associated with `Group`, rather than
|
|
|
|
|
User.
|
|
|
|
|
Had the direction been reversed, the relationship would have been named `IsMemberOf` instead.
|
|
|
|
|
See [Direction of Relationships](#direction-of-relationships) for more discussions on relationship directionality.
|
|
|
|
|
A specific instance of a relationship, e.g. `urn:li:corpGroup:group1` has a member `urn:li:corpuser:user1`,
|
2019-12-18 18:57:18 -08:00
|
|
|
|
corresponds to an edge in the metadata graph.
|
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
Relationships are meant to be "entity-neutral". In other words, one would expect to use the same `OwnedBy` relationship
|
|
|
|
|
to link a `Dataset` to a `User` and to link a `Dashboard` to a `User`.
|
|
|
|
|
As Pegasus doesn’t allow typing a field using multiple URNs (because they’re all essentially strings), we resort to
|
|
|
|
|
using generic URN type for the source and destination.
|
|
|
|
|
We also introduce a `@Relationship` [annotation](../modeling/extending-the-metadata-model.md/#relationship) to
|
|
|
|
|
limit the allowed source and destination URN types.
|
2019-12-18 18:57:18 -08:00
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
While it’s possible to model relationships in rest.li
|
|
|
|
|
as [association resources](https://linkedin.github.io/rest.li/modeling/modeling#association), which often get stored as
|
|
|
|
|
mapping tables, it is far more common to model them as "foreign keys" field in a metadata aspect. For instance,
|
|
|
|
|
the `Ownership` aspect is likely to contain an array of owner’s corpUser URNs.
|
2019-12-18 18:57:18 -08:00
|
|
|
|
|
2020-05-21 10:49:23 -07:00
|
|
|
|
Below is an example of how a relationship is modeled in PDL. Note that:
|
2024-11-08 08:30:11 -06:00
|
|
|
|
|
|
|
|
|
1. This aspect, `nativeGroupMembership` would be associated with a `corpUser`
|
|
|
|
|
2. The `corpUser`'s aspect points to one or more parent entities of type `corpGroup`
|
2019-12-18 18:57:18 -08:00
|
|
|
|
|
2020-05-21 10:49:23 -07:00
|
|
|
|
```
|
2024-11-08 08:30:11 -06:00
|
|
|
|
namespace com.linkedin.identity
|
2020-05-21 10:49:23 -07:00
|
|
|
|
|
|
|
|
|
import com.linkedin.common.Urn
|
|
|
|
|
|
|
|
|
|
/**
|
2024-11-08 08:30:11 -06:00
|
|
|
|
* Carries information about the native CorpGroups a user is in.
|
2020-05-21 10:49:23 -07:00
|
|
|
|
*/
|
2024-11-08 08:30:11 -06:00
|
|
|
|
@Aspect = {
|
|
|
|
|
"name": "nativeGroupMembership"
|
2019-12-18 18:57:18 -08:00
|
|
|
|
}
|
2024-11-08 08:30:11 -06:00
|
|
|
|
record NativeGroupMembership {
|
|
|
|
|
@Relationship = {
|
|
|
|
|
"/*": {
|
|
|
|
|
"name": "IsMemberOfNativeGroup",
|
|
|
|
|
"entityTypes": [ "corpGroup" ]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nativeGroups: array[Urn]
|
2019-12-18 18:57:18 -08:00
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Direction of Relationships
|
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
As relationships are modeled as directed edges between nodes, it’s natural to ask which way should it be pointing,
|
|
|
|
|
or should there be edges going both ways? The answer is, "doesn’t really matter." It’s rather an aesthetic choice than
|
|
|
|
|
technical one.
|
2019-12-18 18:57:18 -08:00
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
For one, the actual direction doesn’t really impact the execution of graph queries. Most graph DBs are fully capable of
|
|
|
|
|
traversing edges in reverse direction efficiently.
|
2019-12-18 20:28:47 -08:00
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
That being said, generally there’s a more "natural way" to specify the direction of a relationship, which closely relate
|
|
|
|
|
to how the metadata is stored. For example, the membership information for an LDAP group is generally stored as a list
|
|
|
|
|
in group’s metadata. As a result, it’s more natural to model a `HasMember` relationship that points from a group to a
|
|
|
|
|
member, instead of a `IsMemberOf` relationship pointing from member to group.
|
2019-12-18 18:57:18 -08:00
|
|
|
|
|
2020-08-18 05:13:01 -07:00
|
|
|
|
## High Cardinality Relationships
|
|
|
|
|
|
2024-11-08 08:30:11 -06:00
|
|
|
|
See [this doc](../advanced/high-cardinality.md) for suggestions on how to best model relationships with high
|
|
|
|
|
cardinality.
|