snippetsqlMinor
How to represent class table inheritance (current DBMS-specific way please)?
Viewed 0 times
representpleasewayinheritancedbmscurrenthowclassspecifictable
Problem
I want to implement class either-or table inheritance (Account, CatAccountDetails, DogAccountDetails) in SQL Server.
I found a recommendation for MySQL:
How do I map an IS-A relationship into a database?
Basically, it is:
Adding a type column that is constrained to a single value (e.g. a 'C' column in CatAccountDetails) feels just a little hackish, so I wondered if there is a feature in SQL Server to enable this scenario?
Also, if this is the way to do it, should I define something additionally to prevent this 'unused' column from degrading performance when my ORM (Entity Framework) requests a table join, like create an additional foreign key on just the PK?
The main problem is that
I found a recommendation for MySQL:
How do I map an IS-A relationship into a database?
Basically, it is:
- use identical primary keys between the parent table (Account) and the subtype tables (CatAccountDetails, DogAccountDetails)
- add a subtype discriminator column to the parent table and the subtype tables
- include both the shared primary keys and subtype columns in a foreign key constraint from subtype to parent type tables
Adding a type column that is constrained to a single value (e.g. a 'C' column in CatAccountDetails) feels just a little hackish, so I wondered if there is a feature in SQL Server to enable this scenario?
Also, if this is the way to do it, should I define something additionally to prevent this 'unused' column from degrading performance when my ORM (Entity Framework) requests a table join, like create an additional foreign key on just the PK?
The main problem is that
CatAccountDetails will have different columns from DogAccountDetails. Cats have both different and far more properties than dogs in my application. Side note, 'cats' and 'dogs' represent three categories of website members in my current scenario.Solution
Ultimately, I implemented ypercube's suggestion from comments:
The "type" column can be defined as a computed (but constant) column in SQL-Server. I think it has to be
This worked well both for performance and compatibility with with my tools (Entity Framework <= 6.0):
This mapped well to my implementation of multiple discrete account types, Recruiter and Candidate, on my Job Board.
The "type" column can be defined as a computed (but constant) column in SQL-Server. I think it has to be
PERSISTED though so it can participate in the Foreign Key constraint.This worked well both for performance and compatibility with with my tools (Entity Framework <= 6.0):
CREATE TABLE [dbo].[Account](
[Id] [int] IDENTITY(1000,1) NOT NULL PRIMARY KEY CLUSTERED,
[CommunityRole] [int] NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
CONSTRAINT [UX_Derived_Relation] UNIQUE ([Id], [CommunityRole]))
CREATE TABLE [dbo].[Recruiter](
[Id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[CommunityRole] AS ((1)) PERSISTED NOT NULL,
[RecruiterSpecificValue] [int] NOT NULL,
FOREIGN KEY ([Id], [CommunityRole]) REFERENCES Account([Id], [CommunityRole]))
CREATE TABLE [dbo].[Candidate](
[Id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[CommunityRole] AS ((2)) PERSISTED NOT NULL,
[CandidateSpecificValue] [int] NOT NULL,
FOREIGN KEY ([Id], [CommunityRole]) REFERENCES Account([Id], [CommunityRole]))This mapped well to my implementation of multiple discrete account types, Recruiter and Candidate, on my Job Board.
Code Snippets
CREATE TABLE [dbo].[Account](
[Id] [int] IDENTITY(1000,1) NOT NULL PRIMARY KEY CLUSTERED,
[CommunityRole] [int] NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
CONSTRAINT [UX_Derived_Relation] UNIQUE ([Id], [CommunityRole]))
CREATE TABLE [dbo].[Recruiter](
[Id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[CommunityRole] AS ((1)) PERSISTED NOT NULL,
[RecruiterSpecificValue] [int] NOT NULL,
FOREIGN KEY ([Id], [CommunityRole]) REFERENCES Account([Id], [CommunityRole]))
CREATE TABLE [dbo].[Candidate](
[Id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[CommunityRole] AS ((2)) PERSISTED NOT NULL,
[CandidateSpecificValue] [int] NOT NULL,
FOREIGN KEY ([Id], [CommunityRole]) REFERENCES Account([Id], [CommunityRole]))Context
StackExchange Database Administrators Q#37443, answer score: 4
Revisions (0)
No revisions yet.