Tuesday, October 09, 2012

Data Modelling


Lately I have been doing some heavy duty data modelling  Let me give you some insights about how i do it, some tips and tricks and how i feel the designing area is being improvised around the world.
What I have felt over the years is that if the design is good, the burden of coding is hugely reduced. If its not, it has its toll on maintenance and extending the system. Coding becomes messy catering to the business needs and ultimately you lose the visibility of system's whereabouts. Since last 6 years that I have been coding I have seen some kickass designs and some designs that will make you puke.  [Recently I saw a Ted talk: You put your image and character in the systems you design. So be careful]
Believe me when I say you need to be able to see where the organization is going 10-20 yrs down the line if you are designing the data model of the business. Even a small SMB can grow into a large one. So if your initial design is not a good one (or should I say NOT adaptable enough), then you have to probably start from scratch leave alone reusing.
How do we do it ?
I usually go for a generic one. This makes me to think of all possible use cases that the system is going to encounter. Then usually we go for a data driven design model. That is,  a design model where the data decides how the system will behave and all the workflows.  At some point in time we all have done it in one way or the other.  For example, using configuration in web apps.
OR
How will the UI design look like or in other words the UI layer is built to render the design (look and feel and events and logic) from configuration which is stored as data.

What does this imply ?
-This means that you have to build a UI layer (handler) that is very generic, intelligent and able to understand the data and render the design.
-The data model should be very generic and be adaptive to accommodate new workflow and UI changes just by changing data.

Having said that, lately I had an epiphany that why not the data model itself be stored as data? That would be awesome! Tomorrow if you going to have a new feature design then there is no need to go for a new design just store it as data i.e. store metadata as data and render the user data as maps to this data.
Most of you have been doing or using it without realizing it. For e.g. Flexible Attributes and Automated website creation sites available on the internet. With in-memory DBs being the buzz word lately anything is possible. A recipe of HTML 5, a server-side scripting language, in-memory DB, jQuery, XML and Cloud Offerings (Web and worker roles) and the boundaries are beginning to look hazy. But on that later.
Recently I read an article by SAP where it was clearing the concerns raised by Oracle over SAP HANA. It said, we do not need the overheads of indexing, materialized views, paging, etc. to traverse/manipulate the data because the BigData is in memory (RAM). It prevents or eliminates the overheads from existing itself. One of the facts, that Oracle had failed to look into.
I realized one more thing. It almost eliminates the use asynchronous programming because the entire data is available readily to DBMS; I want this data...here you go ! OR Modify this data...already done !
Whoa ! Whoa ! Now you start to realize what Time-Space trade-off meant which you read about in college.
Ok now time for some tips on data modelling.
If you have read DBMS and done E-R diagrams thoroughly then you need not read this.
I will simply explain how to decide where to establish which relationship (and behaviour  between entities. i.e. 1:N, N:1 or N:N and Parental using scenarios.
Tip: When you think of creating relationship between entities don't think in terms of entity or tables think in context of entity records or table rows.
1:N
Parent(1)-Child(N) records. 1:N relationship is usually created where there is a plausible parent-child kind of relationship and the existence of a child record is of very less value without the parent record and the same child record will bear no significance if it is associated to another parent record. It does not mean that if a parent record is deleted the child will have no significance at all. For e.g. Order records under Customer records. It is obvious the child order record should not be associated with another parent customer record. If the Customer is deleted the Order will still be used to calculate the revenue. You should configured cascading delete only if the orphaned child records have no significance at all.

N:1
It is the opposite of 1:N. When you create a 1:N relation it automatically creates a N:1 from the other side i.e. Child:Parent::N:1.
What the N:1 relation signify is that A parent can have many children but one child cannot have more than one parent. It is like branches under a single trunk. A branch can originate from a single trunk of course and not from many.

A tricky scenario where you might establish a N:1 is where you want to denote a "type" or "group" or "category" to a record. The "groups" or "categories" will be a master list here. In other words the Group:Record::1:N. You may do this when you are sure that the record will be solely belong to that only one type or group or category. What if the record can also belong to multiple groups or categories? For e.g. the relation between Employees:Languages. One employee can speak multiple languages. Here you establish a direct N:N relationship.

N:N Direct and N:N Intersect
N:N Direct is illustrated in the above example. In this an intersect table/entity is built which only maps the two records in relation and nothing more (using foreign keys).
Consider the above scenario, what if you also want to know how proficient an employee is in languages which he speaks i.e. can he speak, read, write, comprehend. If you want to store this data then you have to establish a N:N Intersect relationship in which the intersect entity or table will have one more attribute/column which stores the proficiency level of the language which the employee is related to i.e. Employee1 speaks English, Employee1 comprehends German.
Parental relation is a concept involving 1:N with some constraints i.e. Cascading or restricting or removing foreign keys for DML actions such as Update, Delete, Deactivate, Share, Assign, Associate(Parent or Reparent), etc. on child records and parent records when the action is performs on one part of the relation i.e. either on the parent or the child.
If you follow the above then you automatically go for 3NF normalization and eliminate almost all data redundancies. 
  
If you want to focus on faster data retrieval then you should go for de-normalized and indexed (non-materialized) "views".
But really today we just need to focus on organizing data well so that reporting can be done. If we have will BCNF then we are fine. We rarely come across 4NF and even if we do, we unknowingly resolve it using Intersect N:N. There will be some data redundancies in this case though.