mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-15 01:54:43 +00:00
Split dbo schema into per-domain SQL schemas (#274)
This commit is contained in:
@@ -15,33 +15,51 @@ convention. For the vertical-slice code that talks to this schema, see
|
||||
|
||||
## Schema
|
||||
|
||||
The full schema lives under
|
||||
`web/backend/Database/Database.Migrations/scripts/01-schema/` with one numbered
|
||||
script per table.
|
||||
The schema is split into six SQL Server schemas, one per feature area, each
|
||||
living in its own numbered folder under
|
||||
`web/backend/Database/Database.Migrations/scripts/`. The folder numbers
|
||||
(`01`-`06`) fix the load order so foreign-key dependencies resolve — DbUp runs
|
||||
embedded scripts in alphabetical-by-resource-name order, so e.g. `04-Brewery`
|
||||
(which references `Auth`, `Geolocation`, and `Media`) runs after all three.
|
||||
Each folder's `00-Schema.sql` creates its SQL schema before its tables run:
|
||||
|
||||
```
|
||||
01-schema
|
||||
├── 01-UserAccount.sql
|
||||
├── 02-Photo.sql
|
||||
├── 03-UserVerification.sql
|
||||
├── 04-UserCredential.sql
|
||||
├── 05-UserFollow.sql
|
||||
├── 06-Country.sql
|
||||
├── 07-StateProvince.sql
|
||||
├── 08-City.sql
|
||||
├── 09-BreweryPost.sql
|
||||
├── 10-BreweryPostLocation.sql
|
||||
├── 11-BreweryPostPhoto.sql
|
||||
├── 12-BeerStyle.sql
|
||||
├── 13-BeerPost.sql
|
||||
├── 14-BeerPostPhoto.sql
|
||||
├── 15-BeerPostComment.sql
|
||||
├── 16-UserProfile.sql
|
||||
└── 17-UserAvatar.sql
|
||||
scripts
|
||||
├── 01-Auth (UserAccount, UserVerification, UserCredential)
|
||||
│ ├── 00-Schema.sql
|
||||
│ ├── 01-UserAccount.sql
|
||||
│ ├── 02-UserVerification.sql
|
||||
│ └── 03-UserCredential.sql
|
||||
├── 02-Geolocation (Country, StateProvince, City)
|
||||
│ ├── 00-Schema.sql
|
||||
│ ├── 01-Country.sql
|
||||
│ ├── 02-StateProvince.sql
|
||||
│ └── 03-City.sql
|
||||
├── 03-Media (Photo)
|
||||
│ ├── 00-Schema.sql
|
||||
│ └── 01-Photo.sql
|
||||
├── 04-Brewery (BreweryPost, BreweryPostLocation, BreweryPostPhoto)
|
||||
│ ├── 00-Schema.sql
|
||||
│ ├── 01-BreweryPost.sql
|
||||
│ ├── 02-BreweryPostLocation.sql
|
||||
│ └── 03-BreweryPostPhoto.sql
|
||||
├── 05-Beer (BeerStyle, BeerPost, BeerPostPhoto, BeerPostComment)
|
||||
│ ├── 00-Schema.sql
|
||||
│ ├── 01-BeerStyle.sql
|
||||
│ ├── 02-BeerPost.sql
|
||||
│ ├── 03-BeerPostPhoto.sql
|
||||
│ └── 04-BeerPostComment.sql
|
||||
└── 06-Social (UserFollow, UserProfile, UserAvatar)
|
||||
├── 00-Schema.sql
|
||||
├── 01-UserFollow.sql
|
||||
├── 02-UserProfile.sql
|
||||
└── 03-UserAvatar.sql
|
||||
```
|
||||
|
||||
Each script is run in order by `Database.Migrations` (DbUp) on startup. Each
|
||||
table is queried directly by the owning feature slice's repository (see
|
||||
Each script is run in order by `Database.Migrations` (DbUp) on startup. Tables
|
||||
are referenced schema-qualified in code (e.g. `Auth.UserAccount`), not under
|
||||
the default `dbo` schema. Each table is queried directly by the owning
|
||||
feature slice's repository (see
|
||||
[Direct SQL via Dapper/ADO.NET](architecture.md#direct-sql-via-dapperadonet)).
|
||||
|
||||
A generated DBML copy of the schema (for import into a diagramming tool such as
|
||||
|
||||
@@ -1,39 +1,46 @@
|
||||
# Database Schema
|
||||
|
||||
Five diagrams, one per schema category — mirrors the `identity` / `media` /
|
||||
`location` / `brewery` / `beer` schema split. Every table also has a
|
||||
Six diagrams, one per SQL Server schema — mirrors the `Auth` / `Geolocation` /
|
||||
`Media` / `Brewery` / `Beer` / `Social` schema split under
|
||||
`web/backend/Database/Database.Migrations/scripts/`. Every table also has a
|
||||
`RowVersion ROWVERSION` column (optimistic concurrency), omitted below for
|
||||
brevity. Tables marked `(*)` have no repository/feature slice yet.
|
||||
|
||||
Boxes with no attribute list (e.g. `Photo` in the identity diagram) are owned by
|
||||
a different schema and shown only to keep the relationship visible; see the
|
||||
Boxes with no attribute list (e.g. `Photo` in the auth diagram) are owned by a
|
||||
different schema and shown only to keep the relationship visible; see the
|
||||
diagram named after that schema for its full definition.
|
||||
|
||||
## Identity (`identity`)
|
||||
## Auth (`Auth`)
|
||||
|
||||
```mermaid
|
||||
--8<-- "web/diagrams/database-schema/identity.mmd"
|
||||
--8<-- "web/diagrams/database-schema/auth.mmd"
|
||||
```
|
||||
|
||||
## Media (`media`)
|
||||
## Social (`Social`)
|
||||
|
||||
```mermaid
|
||||
--8<-- "web/diagrams/database-schema/social.mmd"
|
||||
```
|
||||
|
||||
## Media (`Media`)
|
||||
|
||||
```mermaid
|
||||
--8<-- "web/diagrams/database-schema/media.mmd"
|
||||
```
|
||||
|
||||
## Location (`location`)
|
||||
## Geolocation (`Geolocation`)
|
||||
|
||||
```mermaid
|
||||
--8<-- "web/diagrams/database-schema/location.mmd"
|
||||
--8<-- "web/diagrams/database-schema/geolocation.mmd"
|
||||
```
|
||||
|
||||
## Brewery (`brewery`)
|
||||
## Brewery (`Brewery`)
|
||||
|
||||
```mermaid
|
||||
--8<-- "web/diagrams/database-schema/brewery.mmd"
|
||||
```
|
||||
|
||||
## Beer (`beer`)
|
||||
## Beer (`Beer`)
|
||||
|
||||
```mermaid
|
||||
--8<-- "web/diagrams/database-schema/beer.mmd"
|
||||
|
||||
@@ -6,12 +6,11 @@ config:
|
||||
erDiagram
|
||||
User ||--o{ Cred : "has credentials"
|
||||
User ||--o| Verify : "has verification"
|
||||
|
||||
%% Cross-schema: defined in full in social.mmd / media.mmd / brewery.mmd / beer.mmd
|
||||
User ||--o| Profile : "has profile"
|
||||
User ||--o{ Follow : "follows"
|
||||
User ||--o{ Follow : "followed by"
|
||||
|
||||
%% Cross-schema: defined in full in media.mmd / brewery.mmd / beer.mmd
|
||||
Profile ||--o{ Avatar : "has avatar history"
|
||||
User ||--o{ Photo : "uploads"
|
||||
User ||--o{ Brewery : "posts"
|
||||
User ||--o{ Beer : "posts"
|
||||
@@ -43,16 +42,3 @@ erDiagram
|
||||
uniqueidentifier UserAccountID "FK, UK"
|
||||
datetime VerificationDateTime
|
||||
}
|
||||
|
||||
Profile {
|
||||
uniqueidentifier UserProfileID PK
|
||||
uniqueidentifier UserAccountID "FK, UK"
|
||||
nvarchar Biography
|
||||
}
|
||||
|
||||
Follow {
|
||||
uniqueidentifier UserFollowID PK
|
||||
uniqueidentifier UserAccountID FK
|
||||
uniqueidentifier FollowingID FK
|
||||
datetime CreatedAt
|
||||
}
|
||||
@@ -8,10 +8,11 @@ erDiagram
|
||||
Beer ||--o{ BeerPhoto : "has photos"
|
||||
Beer ||--o{ BeerComment : "has comments"
|
||||
|
||||
%% Cross-schema: defined in full in identity.mmd / brewery.mmd / media.mmd
|
||||
%% Cross-schema: defined in full in auth.mmd / brewery.mmd / media.mmd
|
||||
User ||--o{ Beer : "posts"
|
||||
Brewery ||--o{ Beer : "brews"
|
||||
User ||--o{ BeerComment : "comments"
|
||||
BeerPhoto }o--|| Photo : "uses photo"
|
||||
|
||||
BeerStyle {
|
||||
uniqueidentifier BeerStyleID PK
|
||||
@@ -41,3 +42,10 @@ erDiagram
|
||||
datetime CreatedAt
|
||||
datetime UpdatedAt "nullable"
|
||||
}
|
||||
|
||||
BeerPhoto {
|
||||
uniqueidentifier BeerPostPhotoID PK
|
||||
uniqueidentifier BeerPostID FK
|
||||
uniqueidentifier PhotoID FK
|
||||
datetime LinkedAt
|
||||
}
|
||||
|
||||
@@ -9,8 +9,10 @@ erDiagram
|
||||
Brewery ||--o{ BreweryPhoto : "has photos"
|
||||
Brewery ||--o{ Beer : "brews"
|
||||
|
||||
%% Cross-schema: defined in full in identity.mmd / location.mmd / media.mmd / beer.mmd
|
||||
%% Cross-schema: defined in full in auth.mmd / geolocation.mmd / media.mmd / beer.mmd
|
||||
User ||--o{ Brewery : "posts"
|
||||
BreweryLocation }o--|| City : "located in"
|
||||
BreweryPhoto }o--|| Photo : "uses photo"
|
||||
|
||||
Brewery {
|
||||
uniqueidentifier BreweryPostID PK
|
||||
@@ -20,3 +22,20 @@ erDiagram
|
||||
datetime CreatedAt
|
||||
datetime UpdatedAt "nullable"
|
||||
}
|
||||
|
||||
BreweryLocation {
|
||||
uniqueidentifier BreweryPostLocationID PK
|
||||
uniqueidentifier BreweryPostID "FK, UK"
|
||||
nvarchar AddressLine1
|
||||
nvarchar AddressLine2 "nullable"
|
||||
nvarchar PostalCode
|
||||
uniqueidentifier CityID FK
|
||||
geography Coordinates "nullable"
|
||||
}
|
||||
|
||||
BreweryPhoto {
|
||||
uniqueidentifier BreweryPostPhotoID PK
|
||||
uniqueidentifier BreweryPostID FK
|
||||
uniqueidentifier PhotoID FK
|
||||
datetime LinkedAt
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
erDiagram
|
||||
Country ||--o{ StateProvince : "has"
|
||||
StateProvince ||--o{ City : "has"
|
||||
City ||--o{ BreweryLocation : "located in"
|
||||
|
||||
%% Cross-schema: defined in full in brewery.mmd
|
||||
Brewery ||--o| BreweryLocation : "has location"
|
||||
City ||--o{ BreweryLocation : "located in"
|
||||
|
||||
Country {
|
||||
uniqueidentifier CountryID PK
|
||||
@@ -24,13 +23,3 @@ erDiagram
|
||||
nvarchar CityName
|
||||
uniqueidentifier StateProvinceID FK
|
||||
}
|
||||
|
||||
BreweryLocation {
|
||||
uniqueidentifier BreweryPostLocationID PK
|
||||
uniqueidentifier BreweryPostID "FK, UK"
|
||||
nvarchar AddressLine1
|
||||
nvarchar AddressLine2 "nullable"
|
||||
nvarchar PostalCode
|
||||
uniqueidentifier CityID FK
|
||||
geography Coordinates "nullable"
|
||||
}
|
||||
@@ -4,41 +4,16 @@ config:
|
||||
---
|
||||
|
||||
erDiagram
|
||||
User ||--o{ Photo : "uploads"
|
||||
|
||||
%% Cross-schema: defined in full in auth.mmd / social.mmd / brewery.mmd / beer.mmd
|
||||
Avatar }o--|| Photo : "uses photo"
|
||||
Photo ||--o{ BreweryPhoto : "used in"
|
||||
Photo ||--o{ BeerPhoto : "used in"
|
||||
|
||||
%% Cross-schema: defined in full in identity.mmd / brewery.mmd / beer.mmd
|
||||
Profile ||--o{ Avatar : "has avatar history"
|
||||
User ||--o{ Photo : "uploads"
|
||||
Brewery ||--o{ BreweryPhoto : "has photos"
|
||||
Beer ||--o{ BeerPhoto : "has photos"
|
||||
|
||||
Photo {
|
||||
uniqueidentifier PhotoID PK
|
||||
nvarchar Hyperlink "nullable"
|
||||
uniqueidentifier UploadedByID FK
|
||||
datetime UploadedAt
|
||||
}
|
||||
|
||||
Avatar {
|
||||
uniqueidentifier UserAvatarID PK
|
||||
uniqueidentifier UserProfileID FK
|
||||
uniqueidentifier PhotoID FK
|
||||
datetime2 ValidFrom
|
||||
datetime2 ValidTo "nullable; at most one row per UserProfileID has ValidTo IS NULL (active avatar)"
|
||||
}
|
||||
|
||||
BreweryPhoto {
|
||||
uniqueidentifier BreweryPostPhotoID PK
|
||||
uniqueidentifier BreweryPostID FK
|
||||
uniqueidentifier PhotoID FK
|
||||
datetime LinkedAt
|
||||
}
|
||||
|
||||
BeerPhoto {
|
||||
uniqueidentifier BeerPostPhotoID PK
|
||||
uniqueidentifier BeerPostID FK
|
||||
uniqueidentifier PhotoID FK
|
||||
datetime LinkedAt
|
||||
}
|
||||
|
||||
34
docs/web/diagrams/database-schema/social.mmd
Normal file
34
docs/web/diagrams/database-schema/social.mmd
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
config:
|
||||
layout: elk
|
||||
---
|
||||
|
||||
erDiagram
|
||||
User ||--o| Profile : "has profile"
|
||||
User ||--o{ Follow : "follows"
|
||||
User ||--o{ Follow : "followed by"
|
||||
Profile ||--o{ Avatar : "has avatar history"
|
||||
|
||||
%% Cross-schema: defined in full in auth.mmd / media.mmd
|
||||
Avatar }o--|| Photo : "uses photo"
|
||||
|
||||
Profile {
|
||||
uniqueidentifier UserProfileID PK
|
||||
uniqueidentifier UserAccountID "FK, UK"
|
||||
nvarchar Biography
|
||||
}
|
||||
|
||||
Follow {
|
||||
uniqueidentifier UserFollowID PK
|
||||
uniqueidentifier UserAccountID FK
|
||||
uniqueidentifier FollowingID FK
|
||||
datetime CreatedAt
|
||||
}
|
||||
|
||||
Avatar {
|
||||
uniqueidentifier UserAvatarID PK
|
||||
uniqueidentifier UserProfileID FK
|
||||
uniqueidentifier PhotoID FK
|
||||
datetime2 ValidFrom
|
||||
datetime2 ValidTo "nullable; at most one row per UserProfileID has ValidTo IS NULL (active avatar)"
|
||||
}
|
||||
Reference in New Issue
Block a user