I have a table with huge number of columns say 100.
This single table with name say records stores multiple types of records, kinda single table inheritance. I want to design SQL-Alchemy modles like this.
Class BaseRecord(db.Model):
## common attributes their getter and setter here
Class RecordOne(BaseRecord):
## specific attributes and their getter and setter here
Class RecordTwo(BaseRecord):
## specific attributes and their getter and setter here
Class Record(RecordOne, RecordTwo):
## functions to query records table here
Problem here is that ORM mapper only maps RecordOne class attributes to Record. I can not insert anything related to RecordTwo using Record class.
I want the freedom that if i know type of record i can insert using RecordOne or RecordTwo or if i don't know the type i should be able to insert using Record
Related
I have the below UML class diagram with Abstract Class, and sub-Classes that extends from it. and i want to make an ER diagram using this class diagram.
My question is how can i represent the Abstract class in ER diagram ? as a Table ? or should i just ignore it ?
Thank you.
There are basically three choices to translate generalization into a database model
1. One table per concrete class
Create tables Admin, Teacher and Student. Each of these table contain columns for all of the attributes and relations of User
Pro
All fields of a concrete subclass are in the same table, so no join needed to get all Student data
Easy data validation constraints (such as mandatory fields for Student)
Con
All fields of User are duplicated in each subclass table
Foreign keys to User have to be split into three FK fields. One for Admin, one for Teacher and one for Student.
2. On table for whole generalization set
In this case you just have one table call User that contains all fields of User + all fields of all sub-classes of User
Pro
All fields are in the same table, so no join needed to get all User data
No splitting of FK's to User
Con
There are a bunch of fields that are never used. All fields specific for Student and Teacher are never filled in for Admins and vice versa
Data validation such as mandatory fields for a concrete class such as Student become rather complex as it is no longer a simple Not Null constraint.
3. One table per concrete class, and one for the superclass
In this case you create tables for each of the concrete sub-classes and you create a table for the class User. Each of the concrete sub-class tables has a mandatory FK to User
Pro
Most normalized schema: No repeated fields for the attributes of user, and no unused fields.
No splitting of FK's to User
Easy data validation constraints (such as mandatory fields for Student)
Con
You have to query two tables if you want all data of a Student
Complex validation rules to make sure each User record has exactly one Admin, Teacher or Student record.
Which one of these options you choose depends on a number of things such as the number of sub-classes, the number of attributes in either subclass or superclass, the number of FK's to the superclass, and probably a few other things I didn't think about.
Is there to code a superclass in sql oracle or would you code it as a normal class?
this is a part of my er diagram of my super class:
*Sorry, I'm a beginner with sql
There exist several different approaches for this:
store all data in a single table (this table has columns for all parent and child attributes)
use one table per leaf class, store all attributes in this table (no common table)
use one table per class, store only class-specific attributes in this table (use a common table for the base class data, and add FK references to this table in your detail tables)
I'd recommend you grab a copy of Patterns of Enterprise Architecture - it contains exhaustive information on how to handle situations like this.
In most of the web application, i have seen one base class consisting common properties and number of subclasses extending base class . So my question here is which strategy we should go for among Table Per Subclass Vs Table Per concrete class. I personally feel we should go for table per subclass because in future if we want to introduce the common column we can do it at one place but in case of concrete class we have to do it in multiple tables. Right?
But yes if we want to fetch all deatils from all child tables i think Table per concrete class will be helpful Because we have to simply union the records from all tables but in case of Table per Sub class along with union we have to introduce the join with parent table which will be extra costlier .Right?
You might be interested in Section 2.12 "Inheritance Mapping Strategies" of the JPA 2.0 specification, as it sums up all possbible inheritance types as well as their advantages and drawbacks. Let me pull out just the most interesting fragments:
2.12.1 Single Table per Class Hierarchy Strategy
This mapping strategy provides good support for polymorphic
relationships between entities and for queries that range over the
class hierarchy. It has the drawback, however, that it requires that
the columns that correspond to state specific to the subclasses be
nullable.
2.12.3 Table per Concrete Class Strategy
This strategy has the following drawbacks:
- It provides poor support for polymorphic relationships.
- It typically requires that SQL UNION queries (or a separate SQL query per subclass) be issued for queries that are intended to range over the class hierarchy.
2.12.2 Joined Subclass Strategy
It has the drawback that it requires that one or more join operations
be performed to instantiate instances of a subclass. In deep class
hierarchies, this may lead to unacceptable performance. Queries that
range over the class hierarchy likewise require joins.
Also, if you're planning to be JPA-compatible, remember that the JPA-provider doesn't have to support TABLE_PER_CLASS strategy type.
I personally feel we should go for table per subclass because in
future if we want to introduce the common column we can do it at one
place but in case of concrete class we have to do it in multiple
tables.
True, but JOINED strategy also provides you the same feature and allows to specify common properties in one table.
Hope that helps!
The Object-Relational Impedance Mismatch
In Object Model, while creating object we may require to use inheritance i.e. Generalization as follows:
In Relational Model, the above Generalization(not association i.e. one-to-one or many-to-many) can achieve in Hibernate ORM with the following three inheritance mapping strategies:
Table Per Class i.e. for Hierarchy only one table
Table Per Concrete class i.e. One table for each concrete class not for super class
Table Per Subclass i.e. One table fore each class
In this strategy, we can map the whole hierarchy into single table, here we use one more discriminator column i.e. TYPE.
In this strategy, tables are created as per class but related by foreign key. So there are no duplicate columns.
In this strategy, tables are created as per class but related by foreign key. So there are no duplicate columns.
image source
My model looks like this:
InsurancePolicy
VehicleInsurancePolicy
AbcInsurancePolicy
DefInsurancePolicy
HomeInsurancePolicy
GhiInsurancePolicy
PqrInsurancePolicy
SomeOtherInsurancePolicy
... etc
where InsurancePolicy is an abstract class which is the base class for all concrete implementations of insurance policies. AbcInsurancePolicy , DefInsurancePolicy , etc are implementations which correspond to a certain insurance products. Sometimes I define other abstract classes for subgroups of policies with a subset of common fields (like VehicleInsurancePolicy).
I mapped this classes using a "Table per subclass, using a discriminator" strategy. The InsurancePolicy table contains about 60 fields, and each joined table adds from 10 to 30 fields. I used this strategy because:
I have a lot of subclasses with a lot of fields. A table-per-class-hierarchy strategy would end having a single table with a lot of null columns.
I want to be able to extend the application by adding other subclasses without changing the schema of InsurancePolicy table.
The InsurancePolicy is used often as a many-to-one relationship in other entities like Payment, Document etc.
NHibernate generates a lot of left-outer-joins when querying for InsurancePolicy because it doesn't know the type. This is very inefficient as I have a lot of tables to join. The problem becomes even worse when lazy-loading many-to-one properties containing an InsurancePolicy because it is used quite a lot in my model. The concrete implementations are used rarely, only in edit/details scenarios where it is specified the actual type and only the needed tables are joined.
Then I used a combination of discrimator + join. Thus the InsurancePolicy table contains the information about the type. Unfortunately a "join" mapping doesn't support lazy-loading. I tried setting fetch="select", however these generates N+1 selects when querying for multiple insurance policies.
// select from 1 table, "join" class must be lazy-loaded on access
Session.Get<InsurancePolicy>(5)
// select includes a join, since we explicitly specified a concrete type
Session.Get<SomeConcreteInsurancePolicy>(5)
So my questions are:
Is there a way to extend NHibernate to make it work like above?
Is there another way of mapping these large / complex class hierarchies?
Based on this:
The concrete implementations are used rarely, only in edit/details scenarios
I recommend that you break up InsurancePolicy in two:
InsurancePolicy, containing only the properties from the current base class
PolicyDetails, an abstract base class for the hierarchy.
There's a one-to-one relationship between those two classes.
The beauty of this is that you don't have to change anything else (except a minor change in the policy edit views, to point them to the new relationship)
I'm reading Pro JPA 2. The book talks begins by talking about ORM in the first few pages.
It talks about mapping a single Java class named Employee with the following instance variables - id,name,startDate, salary.
It then goes on to the issue of how this class can be represented in a relational database and suggests the following scheme.
table A: emp
id - primary key
startDate
table B: emp_sal
id - primary key in this table, which is also a foreign key referencing the 'id' column in table A.
It thus seems to suggest that persisting an Employee instance to the database would require operations on two(multiple) tables.
Should the Employee class have an instance variable 'salary' in the first place?
I think it should possibly belong to a separate class (Class salary maybe?) representing salary and thus the example doesn't seem very intuitive.
What am I missing here?
First, the author explains that there are multiples ways to represent a class in a database: sometimes the mapping of a class to a table is straightforward, sometimes you don't have a direct correspondence between attributes and columns, sometimes a single class is represented by multiples tables:
In scenario (C), the EMP table has
been split so that the salary
information is stored in a separate
EMP_SAL table. This allows the
database administrator to restrict
SELECT access on salary information to
those users who genuinely require it.
With such a mapping, even a single
store operation for the Employee class
now requires inserts or updates to two
different tables.
So even storing the data from a single class in a database can be a challenging exercise.
Then, he describes how relationships are different. At the object level model, you traverse objects via their relations. At the relational model level, you use foreign keys and joins (sometimes via a join table that doesn't even exist at the object model level).
Inheritance is another "problem" and can be "simulated" in various ways at the relational model level: you can map an entire hierarchy into a single table, you can map each concrete class to its own table, you can map each class to its own table.
In other words, there is no direct and unique correspondence between an object model and a relational model. Both rely on different paradigms and the fit is not perfect. The difference between both is known as the impedance mismatch, which is something ORM have to deal with (allowing the mapping between an object model and the many possible representations in a relation model). And this is what the whole section you're reading is about. This is also what you missed :)