-
Notifications
You must be signed in to change notification settings - Fork 38
importing-relational-graph - new course #453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| :page-ad-title: Learn how to import relational data into Neo4j with GraphAcademy | ||
| :page-ad-description: This 3-hours course explores the options for importing data into Neo4j. | ||
| :page-ad-link: https://graphacademy.neo4j.com/courses/importing-fundamentals/?ref=docs-ad-importing-fundamentals | ||
| :page-ad-underline-role: button | ||
| :page-ad-underline: Enroll for free |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| = Importing Relational Data into Neo4j | ||
| :categories: beginners:4, start:4, data-analysis:4, reporting:4, software-development:4, foundation:4 | ||
| :status: active | ||
| :next: importing-cypher | ||
| :duration: 3 hours | ||
| :caption: Learn how to import relational SQL data into Neo4j | ||
| :usecase: blank-sandbox | ||
| :key-points: Migrating from relational to graph databases, Transforming SQL data models, Using Neo4j Data Importer, Working with PostgreSQL and Northwind | ||
|
|
||
|
|
||
| == Course Description | ||
|
|
||
| Welcome to Importing Relational Data into Neo4j! | ||
|
|
||
| In this course, you will learn how to migrate data from relational databases into Neo4j. You will work with the classic Northwind PostgreSQL database and transform it into a graph data model optimized for traversal queries. | ||
|
|
||
| You will learn to: | ||
|
|
||
| * Understand the fundamental differences between relational and graph data models. | ||
| * Analyze relational database schemas to identify entities, relationships, and properties. | ||
| * Use PostgreSQL and Postico or pgAdmin to explore and query relational data. | ||
| * Transform relational tables into graph nodes and relationships. | ||
| * Use the Neo4j Data Importer to import relational data into a Neo4j Aura instance. | ||
| * Set unique IDs, constraints, and indexes to ensure data quality and query performance. | ||
|
|
||
| You will work hands-on with the Northwind database, a sample relational database representing a fictional company's sales data, and migrate it into a graph structure that you can query using Cypher. | ||
|
|
||
|
|
||
| === Prerequisites | ||
|
|
||
| Before taking this course, you should have an understanding of: | ||
|
|
||
| * Graph and Neo4j fundamental concepts | ||
| * Basic Cypher queries | ||
| * Relational database concepts and SQL | ||
| * Graph data modeling principles | ||
|
|
||
| Completing the following courses in GraphAcademy is recommended: | ||
|
|
||
| * link:https://graphacademy.neo4j.com/courses/neo4j-fundamentals/[Neo4j Fundamentals^] | ||
| * link:https://graphacademy.neo4j.com/courses/cypher-fundamentals/[Cypher Fundamentals^] | ||
| * link:https://graphacademy.neo4j.com/courses/modeling-fundamentals/[Graph Data Modeling Fundamentals^] | ||
|
|
||
| You will also need: | ||
|
|
||
| * A Neo4j database - choose one of: | ||
| ** **AuraDB Professional** (recommended) - No credit card required, includes Graph Data Science support and Data Importer | ||
| ** **GraphAcademy Sandbox** (quick start) - Free temporary sandbox provided with this course for learning | ||
| ** **Self-managed Neo4j** - Neo4j Desktop or Docker installation | ||
| * PostgreSQL installed (link:https://postgresapp.com/[Postgres.app^] for macOS or link:https://www.postgresql.org/download/[postgresql.org^]) | ||
| * Postico (macOS) or pgAdmin (Windows, Linux, macOS) - optional but recommended | ||
| * The Northwind database (instructions provided in the course) | ||
|
Comment on lines
+44
to
+52
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is too much ambiguity here with so many tools, which will lead to confusion. Stick to AuraDB and remove the rest. |
||
|
|
||
|
|
||
| === Duration | ||
|
|
||
| {duration} | ||
|
|
||
|
|
||
| === What you will learn | ||
|
|
||
| * The fundamental differences between relational and graph data models. | ||
| * How to analyze and understand relational database schemas. | ||
| * Techniques for mapping relational tables to graph nodes and relationships. | ||
| * How to extract data from PostgreSQL databases. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're teaching the concepts of Relational to Graph, not specifically Postgres to Neo4j |
||
| * How to use the Neo4j Data Importer to migrate relational data into a Neo4j Aura instance. | ||
| * Best practices for validating and querying your imported graph data. | ||
|
|
||
|
|
||
| [.includes] | ||
| == This course includes | ||
|
|
||
| * [lessons]#16 lessons# | ||
| * [challenges]#1 hands-on challenge# | ||
| * [quizes]#20 quizzes to support your learning# | ||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#4C8EDA', 'primaryTextColor': '#fff', 'primaryBorderColor': '#2563EB', 'lineColor': '#64748B', 'secondaryColor': '#F59E0B', 'tertiaryColor': '#10B981'}}}%% | ||
| graph TB | ||
| subgraph "Northwind Graph Model - Node Labels" | ||
| C((Customer)) | ||
| O((Order)) | ||
| P((Product)) | ||
| Cat((Category)) | ||
| S((Supplier)) | ||
| E((Employee)) | ||
| Sh((Shipper)) | ||
| end | ||
|
|
||
| subgraph "Source Tables" | ||
| T1[customers table] | ||
| T2[orders table] | ||
| T3[products table] | ||
| T4[categories table] | ||
| T5[suppliers table] | ||
| T6[employees table] | ||
| T7[shippers table] | ||
| end | ||
|
|
||
| T1 -->|becomes| C | ||
| T2 -->|becomes| O | ||
| T3 -->|becomes| P | ||
| T4 -->|becomes| Cat | ||
| T5 -->|becomes| S | ||
| T6 -->|becomes| E | ||
| T7 -->|becomes| Sh | ||
|
|
||
| style C fill:#4C8EDA,stroke:#2563EB,color:#fff | ||
| style O fill:#F59E0B,stroke:#D97706,color:#fff | ||
| style P fill:#10B981,stroke:#059669,color:#fff | ||
| style Cat fill:#8B5CF6,stroke:#7C3AED,color:#fff | ||
| style S fill:#EC4899,stroke:#DB2777,color:#fff | ||
| style E fill:#06B6D4,stroke:#0891B2,color:#fff | ||
| style Sh fill:#F97316,stroke:#EA580C,color:#fff | ||
|
Comment on lines
+31
to
+37
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#4C8EDA', 'primaryTextColor': '#fff', 'lineColor': '#64748B'}}}%% | ||
| graph LR | ||
| subgraph "Graph Model" | ||
| C((Customer)) | ||
| O((Order)) | ||
| C -->|PLACED| O | ||
| end | ||
|
|
||
| subgraph "Relational Model" | ||
| CT[customers table<br/>customer_id PK] | ||
| OT[orders table<br/>order_id PK<br/>customer_id FK] | ||
| CT -.->|referenced by| OT | ||
| end | ||
|
|
||
| style C fill:#4C8EDA,stroke:#2563EB,color:#fff | ||
| style O fill:#F59E0B,stroke:#D97706,color:#fff | ||
| style CT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
| style OT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#06B6D4', 'primaryTextColor': '#fff', 'lineColor': '#64748B'}}}%% | ||
| graph LR | ||
| subgraph "Graph Model" | ||
| E((Employee)) | ||
| O((Order)) | ||
| E -->|PROCESSED| O | ||
| end | ||
|
|
||
| subgraph "Relational Model" | ||
| ET[employees table<br/>employee_id PK] | ||
| OT[orders table<br/>order_id PK<br/>employee_id FK] | ||
| ET -.->|referenced by| OT | ||
| end | ||
|
|
||
| style E fill:#06B6D4,stroke:#0891B2,color:#fff | ||
| style O fill:#F59E0B,stroke:#D97706,color:#fff | ||
| style ET fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
| style OT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#F59E0B', 'primaryTextColor': '#fff', 'lineColor': '#64748B'}}}%% | ||
| graph LR | ||
| subgraph "Graph Model" | ||
| O((Order)) | ||
| S((Shipper)) | ||
| O -->|SHIPPED_BY| S | ||
| end | ||
|
|
||
| subgraph "Relational Model" | ||
| OT[orders table<br/>order_id PK<br/>ship_via FK] | ||
| ST[shippers table<br/>shipper_id PK] | ||
| OT -.->|references| ST | ||
| end | ||
|
|
||
| style O fill:#F59E0B,stroke:#D97706,color:#fff | ||
| style S fill:#F97316,stroke:#EA580C,color:#fff | ||
| style OT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
| style ST fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#F59E0B', 'primaryTextColor': '#fff', 'lineColor': '#64748B'}}}%% | ||
| graph LR | ||
| subgraph "Graph Model" | ||
| O((Order)) | ||
| P((Product)) | ||
| O -->|"CONTAINS<br/>{quantity, unitPrice, discount}"| P | ||
| end | ||
|
|
||
| subgraph "Relational Model - Junction Table" | ||
| OT[orders table<br/>order_id PK] | ||
| ODT[order_details table<br/>order_id FK<br/>product_id FK<br/>quantity<br/>unit_price<br/>discount] | ||
| PT[products table<br/>product_id PK] | ||
| OT -.->|referenced by| ODT | ||
| PT -.->|referenced by| ODT | ||
| end | ||
|
|
||
| style O fill:#F59E0B,stroke:#D97706,color:#fff | ||
| style P fill:#10B981,stroke:#059669,color:#fff | ||
| style OT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
| style ODT fill:#FEF3C7,stroke:#F59E0B,color:#1E293B | ||
| style PT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#10B981', 'primaryTextColor': '#fff', 'lineColor': '#64748B'}}}%% | ||
| graph LR | ||
| subgraph "Graph Model" | ||
| P((Product)) | ||
| C((Category)) | ||
| P -->|IN_CATEGORY| C | ||
| end | ||
|
|
||
| subgraph "Relational Model" | ||
| PT[products table<br/>product_id PK<br/>category_id FK] | ||
| CT[categories table<br/>category_id PK] | ||
| PT -.->|references| CT | ||
| end | ||
|
|
||
| style P fill:#10B981,stroke:#059669,color:#fff | ||
| style C fill:#8B5CF6,stroke:#7C3AED,color:#fff | ||
| style PT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
| style CT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#EC4899', 'primaryTextColor': '#fff', 'lineColor': '#64748B'}}}%% | ||
| graph LR | ||
| subgraph "Graph Model" | ||
| S((Supplier)) | ||
| P((Product)) | ||
| S -->|SUPPLIES| P | ||
| end | ||
|
|
||
| subgraph "Relational Model" | ||
| ST[suppliers table<br/>supplier_id PK] | ||
| PT[products table<br/>product_id PK<br/>supplier_id FK] | ||
| ST -.->|referenced by| PT | ||
| end | ||
|
|
||
| style S fill:#EC4899,stroke:#DB2777,color:#fff | ||
| style P fill:#10B981,stroke:#059669,color:#fff | ||
| style ST fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
| style PT fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#06B6D4', 'primaryTextColor': '#fff', 'lineColor': '#64748B'}}}%% | ||
| graph TB | ||
| subgraph "Graph Model - Employee Hierarchy" | ||
| E1((Employee<br/>CEO)) | ||
| E2((Employee<br/>Manager)) | ||
| E3((Employee<br/>Staff)) | ||
| E4((Employee<br/>Staff)) | ||
|
|
||
| E2 -->|REPORTS_TO| E1 | ||
| E3 -->|REPORTS_TO| E2 | ||
| E4 -->|REPORTS_TO| E2 | ||
| end | ||
|
|
||
| subgraph "Relational Model - Self-Reference" | ||
| ET[employees table<br/>employee_id PK<br/>reports_to FK → employee_id] | ||
| end | ||
|
|
||
| style E1 fill:#06B6D4,stroke:#0891B2,color:#fff | ||
| style E2 fill:#06B6D4,stroke:#0891B2,color:#fff | ||
| style E3 fill:#06B6D4,stroke:#0891B2,color:#fff | ||
| style E4 fill:#06B6D4,stroke:#0891B2,color:#fff | ||
| style ET fill:#E2E8F0,stroke:#94A3B8,color:#1E293B | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#4C8EDA', 'primaryTextColor': '#fff', 'lineColor': '#64748B', 'fontSize': '14px'}}}%% | ||
| graph TB | ||
| subgraph "Complete Northwind Graph Model" | ||
| C((Customer)) | ||
| O((Order)) | ||
| P((Product)) | ||
| Cat((Category)) | ||
| S((Supplier)) | ||
| E((Employee)) | ||
| Sh((Shipper)) | ||
|
|
||
| C -->|PLACED| O | ||
| E -->|PROCESSED| O | ||
| O -->|SHIPPED_BY| Sh | ||
| O -->|"CONTAINS<br/>{qty, price, discount}"| P | ||
| P -->|IN_CATEGORY| Cat | ||
| S -->|SUPPLIES| P | ||
| E -->|REPORTS_TO| E | ||
| end | ||
|
|
||
| style C fill:#4C8EDA,stroke:#2563EB,color:#fff | ||
| style O fill:#F59E0B,stroke:#D97706,color:#fff | ||
| style P fill:#10B981,stroke:#059669,color:#fff | ||
| style Cat fill:#8B5CF6,stroke:#7C3AED,color:#fff | ||
| style S fill:#EC4899,stroke:#DB2777,color:#fff | ||
| style E fill:#06B6D4,stroke:#0891B2,color:#fff | ||
| style Sh fill:#F97316,stroke:#EA580C,color:#fff | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| %%{init: { | ||
| 'theme': 'base', | ||
| 'themeVariables': { | ||
| 'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif', | ||
| 'fontSize': '14px' | ||
| } | ||
| }}%% | ||
| flowchart LR | ||
| subgraph s1[" "] | ||
| A1["<b>1990s</b><br/><br/>1992: Microsoft creates<br/>Northwind as sample<br/>database for Access"] | ||
| end | ||
|
|
||
| subgraph s2[" "] | ||
| A2["<b>2000s</b><br/><br/>Ported to SQL Server<br/>MySQL & PostgreSQL<br/>Standard teaching tool"] | ||
| end | ||
|
|
||
| subgraph s3[" "] | ||
| A3["<b>2010s</b><br/><br/>Countless tutorials<br/>Certification exams<br/>NoSQL migrations"] | ||
| end | ||
|
|
||
| subgraph s4[" "] | ||
| A4["<b>Today</b><br/><br/>Graph migrations<br/>Neo4j resource<br/>Go-to dataset"] | ||
| end | ||
|
|
||
| s1 ~~~ s2 | ||
| s2 ~~~ s3 | ||
| s3 ~~~ s4 | ||
|
|
||
| style s1 fill:transparent,stroke:transparent | ||
| style s2 fill:transparent,stroke:transparent | ||
| style s3 fill:transparent,stroke:transparent | ||
| style s4 fill:transparent,stroke:transparent | ||
|
|
||
| style A1 fill:#3B82F6,stroke:#1D4ED8,stroke-width:1px,color:#FFFFFF | ||
| style A2 fill:#10B981,stroke:#059669,stroke-width:1px,color:#FFFFFF | ||
| style A3 fill:#8B5CF6,stroke:#7C3AED,stroke-width:1px,color:#FFFFFF | ||
| style A4 fill:#F59E0B,stroke:#D97706,stroke-width:1px,color:#FFFFFF |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| %%{init: { | ||
| 'theme': 'base', | ||
| 'themeVariables': { | ||
| 'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif', | ||
| 'fontSize': '14px', | ||
| 'primaryColor': '#DBEAFE', | ||
| 'primaryBorderColor': '#3B82F6' | ||
| } | ||
| }}%% | ||
| flowchart TB | ||
| C["<b>Customers</b><br/>CustomerID | CompanyName | City"] | ||
| O["<b>Orders</b><br/>OrderID | CustomerID | OrderDate"] | ||
| OD["<b>OrderDetails</b><br/>OrderID | ProductID | Quantity | UnitPrice"] | ||
| P["<b>Products</b><br/>ProductID | ProductName | CategoryID"] | ||
| Cat["<b>Categories</b><br/>CategoryID | CategoryName"] | ||
|
|
||
| C -->|"FK: customer_id"| O | ||
| O -->|"FK: order_id"| OD | ||
| P -->|"FK: product_id"| OD | ||
| P -->|"FK: category_id"| Cat | ||
|
|
||
| style C fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#1E293B | ||
| style O fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#1E293B | ||
| style OD fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#1E293B | ||
| style P fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#1E293B | ||
| style Cat fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#1E293B |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| %%{init: { | ||
| 'theme': 'base', | ||
| 'themeVariables': { | ||
| 'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif', | ||
| 'fontSize': '14px' | ||
| } | ||
| }}%% | ||
| flowchart LR | ||
| C(("Customer<br/>Alfreds<br/>Berlin")) | ||
| O(("Order<br/>2024-01-15")) | ||
| P1(("Product<br/>Chai")) | ||
| P2(("Product<br/>Chang")) | ||
| Cat(("Category<br/>Beverages")) | ||
|
|
||
| C -->|PLACED| O | ||
| O -->|"CONTAINS<br/>qty: 10"| P1 | ||
| O -->|"CONTAINS<br/>qty: 5"| P2 | ||
| P1 -->|IN_CATEGORY| Cat | ||
| P2 -->|IN_CATEGORY| Cat | ||
|
|
||
| style C fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#FFFFFF | ||
| style O fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#FFFFFF | ||
| style P1 fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#FFFFFF | ||
| style P2 fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#FFFFFF | ||
| style Cat fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#FFFFFF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Postgres is where the data happens to come from, we shouldn't be teaching them how to use Postico or pgAdmin.