views:

245

answers:

5

Let's say we have a field that can be in more than one type, for instance: string or date or XML datatypes.

Now we have two methods to store this in a database

1- using a string typed field + field defining type: losing "type-aware" sorting capabilities, needs casting

2- separate tables (StringValues,DateValues,Decimal,XML ...etc):a foreign key pointing to a value + field defining type : somehow complicated, performance

the second method may have an extra advantage if only unique values were stored: it will work as an index.

do you have something in mind ?


Note1: Preferably, consider project based on MS SQL Server 2008 and Linq2SQL


Note2: Maybe we will discuss how to implement EAV in another question, I'm asking about EAV in a relational storage.


Note3: Types can change, but not frequently

+5  A: 

It sounds like you're designing an EAV solution, where your table stores values for multiple attributes, one value per row.

EAV is a non-relational design. There's no "right" way to do this with respect to proper rules of relational database design.

The proper design is to store each attribute in a separate column of one table. Give each column the right datatype and a descriptive name. Only store values of the same logical type in each column.

If you need dynamic attributes, use a non-relational data management solution.

Bill Karwin
I couldn't have said it better myself!
James Skidmore
I know it's somehow not following normalization guidelines, but I'm asking about the best way to achieve it with least sacrifices.
Ahmed Khalaf
You're sacrificing virtually *every* advantage of a relational database when you use the EAV design, so you might as well not use a relational database.
Bill Karwin
I know, and I'm asking in case i don't have a better choice :)
Ahmed Khalaf
maybe we will discuss how to implement EAV in another question :D
Ahmed Khalaf
Follow the link I gave about non-relational data management solutions. There's a long list of alternatives there. I also added the `eav` tag to your question. Click that tag to see a bunch of other questions about managing eav.
Bill Karwin
If you still think EAV is your only option, read this excellent article about someone else's experience with EAV: http://www.simple-talk.com/opinion/opinion-pieces/bad-carma/
Bill Karwin
sure I did, but I really need to implement it on RDBMS :) sorry if I cant disclose more details.
Ahmed Khalaf
+1  A: 

I'm not sure this is enough detail to answer the question well. If you are literally asking about the two type case, you might also consider a table with a column for each type and a discriminator. The "right" answer may depend on specifics such as number of distinct types to be supported, speed vs. space constraints, etc.

Some might argue that the least expensive approach is the best one. Specifically, the approach that you believe will require the least cost to understand and maintain (often ~60% of TCO).

With regard to all the advice about not doing this, I agree if possible. On the other hand, SharePoint is one example that shows it's not impossible. Good luck!

Jason Weber
+1  A: 

I'd go with the second option and hide the complexity of the table situation with a couple of views. That way once you get more flexibility your applications can still point to the views without needing to be changed and you can rearrange your underlying tables to something a little cleaner.

Shaun F
+1  A: 

Can you consider using an XML datatype? If so, you can use an attribute/element to define the type.

<string>My string value</string>
<date>24-Nov-1976</date>

Or,

<val type="System.String">My string value</val>
<val type="System.Date">24-Nov-1976</val>

SQL Server 2005+ has some good support for XML indexing that may support your needs.

From a Linq to SQL point of view you can probably have a lightweight class that can map the types to a specific data type; XML de/serialisation may be an option here.

objektivs
what about performance ? if I need to query on values...
Ahmed Khalaf
also indexing is not very efficient
Ahmed Khalaf
Querying on XMl data type slooks like this:SELECT xCol FROM docs WHERE xCol.exist ('/book/@ISBN[. = "0-2016-3361-2"]') = 1I don't have any specifics on XML indexing performance. I think it depends on whether you type your XML. Of course, depending on the scenario this performance cost may be acceptable. You'll only know if you try benchmarking.
objektivs
Why did you use CW?
voyager
Hadn't realised that I had. (PC locks up every now and then so I click impatiently until it comes back.)
objektivs
+1  A: 

If the number of possible types is small, use option 2 (additional tables + foreign key) or use option 3.

Option 3: Use one table with a field of each type and an enum field defining which field is relevant.

If the number of possible types is large or not constant, use option 1 (strings) - you can store dates in strings as YYYY-MM-DD-HH-MM-SS to preserve sorting.

Danny Varod