Question

A Report can have multiple charts. The Chart table looks as follows:

  • Chart -- Id, ChartId, ReportId, ...

The ChartId above can map to the ChartId to either one of the following Chart Types:

  • Line: ChartId, Thickness, YAxis, XAxis, Color, ...
  • Pie: ChartId, Radius, Color, ...
  • Bar: ChartId, Width, Color, Border, ...

I am using SQL Server and unfortunately alternate solutions like using CouchDB etc are not viable options. I also intend to map these tables to entities using Entity Framework.

This design is my first stab and I see multiple problems with this design:

  1. Chart.ReportId cannot be a foreign key on multiple tables so enforcing an FK is a problem.
  2. When running an SQL (Or Linq) query, I'll have to do either run two queries to get the chart type and then query that table. Or, I'll have to run a join against all the tables to get the chart data.
  3. When doing a join against the Chart Types, The ChartId across these tables need to be unique so Chart.ChartId maps to only one of Line.ChartId or Bar.ChartId or Pie.ChartId.
  4. Mapping this with EF will be tricky.

I would imagine this is a common enough problem that there are prescribed solutions and established ways to handle it.

Am I on the right path with the design? And if so, how to overcome the above problems (FK, join, unique id across multiple tables, and mapping).

Solution

This answer is quite comprehensive about the strategies. And SQL Team's article on implementing table inheritance in SQL Server got me where I wanted.

Was it helpful?

Solution

Have you considered putting the Charts in the same table and using a Table per heirarchy inheritance pattern? The link there shows how to implement this in Entity Framework. Whether or not it's viable depends on just how different all those chart types will be and how many fields each will need.

There is also Table per type inheritance which is more similar to what you are already describing.

OTHER TIPS

I'd tackle this with a table inheritance scheme:

Chart (ChartId, ChartTypeId)
   PK (ChartId, ChartTypeId)
   CHECK ChartTypeId IN ('Line', 'Bar', 'Pie')

LineChart (ChartId, ChartTypeId)
   PK (ChartId, ChartTypeId)
   FK (ChartId, ChartTypeId) -> Chart
   CHECK ChartTypeId IN ('Line')

To add a chart, you first add to the "base" Chart table, and then to the appropriate "subtype" chart table. The check constraints keep everything in line.

Line charts. pie charts, and bar charts are specialized forms of charts.

Lookup "generalization specialization relational modeling" for good articles on this pattern.

Or, I'll have to run a join against all the tables to get the chart data.

Yes, and that is fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top