> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parable.work/llms.txt
> Use this file to discover all available pages before exploring further.

# Keys and Relationships

> Discover logical primary keys, foreign keys, and safe relationships between SQL tables.

Parable exposes logical keys and relationships through Flight SQL metadata and
the semantic catalog. Use them to choose joins and understand the grain of a
table.

## Discover keys

| Flight SQL operation | What it returns                                         |
| -------------------- | ------------------------------------------------------- |
| `GetPrimaryKeys`     | The ordered logical primary-key columns for a table.    |
| `GetImportedKeys`    | Foreign keys from a table to referenced tables.         |
| `GetExportedKeys`    | Foreign keys in other tables that reference a table.    |
| `GetCrossReference`  | Relationships between one parent and one foreign table. |

The semantic catalog exposes the same model as `primaryKey` and
`importedForeignKeys` on each table.

<Warning>
  These keys are descriptive metadata. Delta tables and DataFusion do not
  enforce uniqueness, referential integrity, cascades, or other database
  constraint actions.
</Warning>

## Preserve table grain

A main Provider table and its child tables have different keys. For example,
an issue can have many labels, so the parent issue ID repeats in
`providers.github.issues__labels`. Use the complete logical key returned by the
catalog instead of deduplicating a child table on its parent ID.

Provider Plugins define the business key and ordering behavior used to project
source records. Consumers inspect that metadata; they do not redefine it in a
query.

## Prefer semantic joins

Use a relationship from the catalog when one exists. Otherwise, choose columns
that represent the same semantic value or domain key:

* Join `Contact.Email` values across Provider and Workspace tables.
* Join Provider-native IDs only inside the Provider domain that owns them.
* Use `providers.identity.account_associations` when accounts for the same
  person do not share an email.
* Join work items on a real shared domain key, such as a branch name, rather
  than similarly named IDs.

```sql theme={null}
SELECT
  member.email,
  member.name,
  directory.orgunitpath
FROM workspace.users AS member
JOIN providers.google.users AS directory
  ON directory.primaryemail = member.email
```

See the [Provider Pool](/protocols/sql/data-catalog/provider-pool) for identity
tables and cross-Provider examples.
