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.
Related
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
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 :)
The current structure is as follows:
Table RowType: RowTypeID
Table RowSubType: RowSubTypeID
FK_RowTypeID
Table ColumnDef: FK_RowTypeID
FK_RowSubTypeID (nullable)
In short, I'm mapping column definitions to rows. In some cases, those rows have subtype(s), which will have column definitions specific to them. Alternatively, I could hang those column definitions that are specific to subtypes off their own table, or I could combine the data in RowType and RowSubType into one table and work with a single ID, but I'm not sure either is a better solution (if anything, I'd lean towards the latter, as we mostly end up pulling ColumnDefs for a given RowType/RowSubType).
Is the current design SQL blasphemy?
If I keep the current structure, how do I maintain that if RowSubTypeID is specified in ColumnDef, that it must correspond to the RowType specified by RowTypeID? Should I try to enforce this with a trigger or am I missing a simple redesign that would solve the problem?
What you're having trouble with is Fourth Normal Form.
Here's the solution:
Table RowSubType: RowSubTypeID
FK_RowTypeID
UNIQUE(FK_RowTypeID, RowSubTypeID)
Table ColumnDef: ColumnDefID
FK_RowTypeID
UNIQUE(ColumnDefID, FK_RowTypeID)
Table ColumnDefSubType: FK_ColumnDefID } compound foreign key to ColumnDef
FK_RowTypeID } }
FK_RowSubTypeID } compound foreign key to RowSubType
You only need to create a row in the ColumnDefSubType table for columns that have a row subtype. But all references are constrained so you can't create an anomaly.
But for what it's worth, I agree with #Seth's comment about possible over-engineering. I'm not sure I understand how you're using these column defs and row types, but it smells like the Inner-Platform Effect anti-pattern. In SQL, just use metadata to define metadata. Don't try to use data to create a dynamic schema.
See also this excellent story: Bad CaRMa.
Re your comment: In your case I'd recommend using Class Table Inheritance or Concrete Table Inheritance. This means defining a separate table per subtype. But each column of your original text record would go into the respective column of the subtype table. That way you don't need to have your rowtype or rowsubtype tables, it's implicit by defining tables for each subtype. And you don't need your columndefs table, that's implicit by the columns defined in your tables.
See also my answer to Product table, many kinds of product, each product has many parameters or my presentation slides Practical Object-Oriented Models in SQL.
I have to add functionality to an existing application and I've run into a data situation that I'm not sure how to model. I am being restricted to the creation of new tables and code. If I need to alter the existing structure I think my client may reject the proposal.. although if its the only way to get it right this is what I will have to do.
I have an Item table that can me link to any number of tables, and these tables may increase over time. The Item can only me linked to one other table, but the record in the other table may have many items linked to it.
Examples of the tables/entities being linked to are Person, Vehicle, Building, Office. These are all separate tables.
Example of Items are Pen, Stapler, Cushion, Tyre, A4 Paper, Plastic Bag, Poster, Decoration"
For instance a Poster may be allocated to a Person or Office or Building. In the future if they add a Conference Room table it may also be added to that.
My intital thoughts are:
Item
{
ID,
Name
}
LinkedItem
{
ItemID,
LinkedToTableName,
LinkedToID
}
The LinkedToTableName field will then allow me to identify the correct table to link to in my code.
I'm not overly happy with this solution, but I can't quite think of anything else. Please help! :)
Thanks!
It is not a good practice to store table names as column values. This is a bad hack.
There are two standard ways of doing what you are trying to do. The first is called single-table inheritance. This is easily understood by ORM tools but trades off some normalization. The idea is, that all of these entities - Person, Vehicle, whatever - are stored in the same table, often with several unused columns per entry, along with a discriminator field that identifies what type the entity is.
The discriminator field is usually an integer type, that is mapped to some enumeration in your code. It may also be a foreign key to some lookup table in your database, identifying which numbers correspond to which types (not table names, just descriptions).
The other way to do this is multiple-table inheritance, which is better for your database but not as easy to map in code. You do this by having a base table which defines some common properties of all the objects - perhaps just an ID and a name - and all of your "specific" tables (Person etc.) use the base ID as a unique foreign key (usually also the primary key).
In the first case, the exclusivity is implicit, since all entities are in one table. In the second case, the relationship is between the Item and the base entity ID, which also guarantees uniqueness.
Note that with multiple-table inheritance, you have a different problem - you can't guarantee that a base ID is used by exactly one inheritance table. It could be used by several, or not used at all. That is why multiple-table inheritance schemes usually also have a discriminator column, to identify which table is "expected." Again, this discriminator doesn't hold a table name, it holds a lookup value which the consumer may (or may not) use to determine which other table to join to.
Multiple-table inheritance is a closer match to your current schema, so I would recommend going with that unless you need to use this with Linq to SQL or a similar ORM.
See here for a good detailed tutorial: Implementing Table Inheritance in SQL Server.
Find something common to Person, Vehicle, Building, Office. For the lack of a better term I have used Entity. Then implement super-type/sub-type relationship between the Entity and its sub-types. Note that the EntityID is a PK and a FK in all sub-type tables. Now, you can link the Item table to the Entity (owner).
In this model, one item can belong to only one Entity; one Entity can have (own) many items.
your link table is ok.
the trouble you will have is that you will need to generate dynamic sql at runtime. parameterized sql does not typically allow the objects inthe FROM list to be parameters.
i fyou want to avoid this, you may be able to denormalize a little - say by creating a table to hold the id (assuming the ids are unique across the other tables) and the type_id representing which table is the source, and a generated description - e.g. the name value from the inital record.
you would trigger the creation of this denormalized list when the base info is modified, and you could use that for generalized queries - and then resort to your dynamic queries when needed at runtime.
[noob warning!] I need to store some data in some tables where it is like the equivalent of an array of pointers to polymorphic objects. E.g. (pseudo C++)
struct MyData { string name; }
struct MyDataA : MyData { int a,b,c; }
struct MyDataB : MyData { string s; }
MyData * data[100];
I don't really know what google search to enter! How would you store info like this in an SQL database?
My random thoughts:
I could have one table with a column that is the struct identifier and then have redundant columns, but this seems wasteful.
I can have one table for each struct type. These would have a foreign key back to the master array table. But, how do I point to the struct tables?
There's really two major ways to solve this:
table-per-type
table-per-hierarchy
Either of them has its pros and cons.
Table-per-type gives you more tables (one per type), which only store the "delta" from the immediate super class. Worst case, you need to join together a number of tables to finally get all the data together for a single instance of a type. Pros: since you only store what's really relevant for that type into a separate table, you can do this like set NOT NULL restrictions etc. on the database table.
Table-per-hierarchy gives you less tables, but each table represents an entire hierarchy, so it will contains potentially lots of columns which aren't filled (in the rows representating base class types). Also, on the extra columns that make up the derived classes, you cannot set things like NOT NULL restrictions - all those extra columns must be nullable, since they really don't exist in the base classes, so you loose some degree of safety here.
See for yourself - there are two really good articles on how to do this (in Entity Framework, but the principles apply to any database and any data mapping technology):
Demystifying The Code: Table Per Type
Demystifying The Code: Table Per Hierarchy
Hope this helps and gives you some inputs!
Marc
I do the "table-per-sublcass" style from the Hibernate docs.
You make a Person table with all the things you know about a person, plus the PersonID. Then you make a Customer table, with only the data that's unique to a Customer (account balance, etc). Put the PersonID in the Customer table. A WebsiteUser might have a CustomerID in it, and so on down the chain.
One-to-one relationships mapping the IS-A inheritance relationships.
One possibility is an XML field to store the data, this allows searching and retrieving whilst also being relatively easy to serialise. (the question says SQL, but doesn't specify a specfic vendor database, so XML may not work for every DB solution.)
Edit : I'm going to caveat this because it's not entirely clear what needs to be stored / retrieved / purpose etc, so XML may be entirely inappropriate - I'm throwing it out there as a thought provoker instead.