You Asked
I need a database design to maintain the entity, its properties and also to store the historical changes of the property values
Entity: Any object. For example car
Properties: Color, Engine type, Height, Width
Example: I created a main table with obj_id and obj_name. Properties table with prop_id and prop_name
Create table object (obj_id number, obj_name varchar2, created_date, created_by,last_updated_by,start_date,end_date);
insert into object values(1,'Car');
create table obj_prop (prop_id number, prop_name varchar2, created_date, created_by,last_updated_by,start_date,end_date);
insert into obj_prop values (1,'Color');
insert into obj_prop values (2,'Engine_type');
insert into obj_prop values (3,'Height');
insert into obj_prop values (4,'width');
create table obj_prop_assoc (assoc_id number,obj_id number,prop_id number, prop_value varchar2, created_date, created_by,last_updated_by,start_date,end_date);
insert into obj_prop_assoc values (1,1,1,'White');
insert into obj_prop_assoc values (2,1,2,'Diesel');
insert into obj_prop_assoc values (3,1,3,'250cm');
insert into obj_prop_assoc values (4,1,4,'500cm');
So, If any new object/property has to be added I can add in above tables.
Question
1.Is this is the best design to follow?
2. How can I apply constraints on property values?
If I have another table to store different colors
Create table colors(color_id,color_name)
insert into colors(1,'Violet');
insert into colors(2,'Indigo');
insert into colors(3,'Blue');
insert into colors(4,'Green');
insert into colors(5,'Yellow');
insert into colors(6,'Orange');
insert into colors(7,'Red');
Now I want to apply constraint on obj_prop_assoc table prop_name column to have one of the values from the colors table for Color property (Foreign Key Constraint) . How can I do this?
Thanks.
and Chris said...
1. No! This is a form of entity-attribute-value (EAV) model.
There are many problems with this. See this thread:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2314483800346542969 2. You can create the foreign key just like normal. But what if you want do the same for engine types? (petrol, diesel, etc.)
You can create another foreign key on the same column to the engine types table. But now you have a problem. You can't insert any data! (unless you happen to have engine types and colors which are the same).
"Optional" foreign keys, which only applies based on values from other columns are impossible. They apply to all rows in the table.
This is one of the big problems with EAV. It's almost impossible to enforce constraints such as "rows of type color must use values from the color table".
Just create a simple table:
create table cars (
color varcahr2(30),
engine_type varchar2(30),
height number,
width number,
...
);
If you need to track changes to the data you could create some history tables. e.g.:
create table cars_hist (
color varcahr2(30),
engine_type varchar2(30),
height number,
width number,
...
changed_date date,
change_type varchar2(1),
changed_by varchar2(30),
...
);
Then write code/triggers to maintain this.
Or check out flashback data archive. It does this all for you! If you're on 11.2.0.4 it's included in EE (it used to require a separate license).
https://oracle-base.com/articles/12c/flashback-data-archive-fda-enhancements-12cr1
Rating
(2 ratings)
Is this answer out of date? If it is, please let us know via a Comment