views:

38

answers:

2

I am working on an embedment section on my site where users can embed different media from various services, youtube, myspace music, vimeo etc

I am trying to work out the best way to store it. Users do not have to embed all of the options and can only embed one of each type (one video for example).

Initially I thought just have a table with a row per embeded item like so:

  • embedid (auto increment primary key), userid, embedded_item_id (e.g a youtube id)

but then I realised that some embedable items require multiple arguments such as myspace music so I thought id make a table where each user has one row.

  • userid, youtubeid, vimeoid, myspaceid1, myspaceid2

but it seems a bit clumsy especially considering there will always be empty rows as users can not ever have all of them. Does anyone have a better solution?

+1  A: 
  • `EmbededItem' table has columns common to all items.
  • YouTube, Vimeo, MySpace have only columns specific to each one.

alt text

Damir Sudarevic
wow... never expected a picture... hmmm yeh makes a lot of sense... very relational :)
Mark
Why not have one table for all the unique ids with a mapping table for the different service names. With this set up you'd have to add a new table every time you want to add support for a new service. With the mapping table, you just add a new row.
Tom
@Tom, premise here is that each service has one or more specific columns that other services do not have. If they all had only id, the `EmbeddedItem` table would be enough.
Damir Sudarevic
@Damir, I really like this system, one question... would you recommend that type be 'youtube' as it is technically an id and so will be repeated many times... should I not make that relative to a type table? or am I getting over carried away relationally... leading to millions of join's and inefficient queries?
Mark
All the common fields should go into `EmbededItems` table; providing they are (fit into) the same data-type. The Type classifier may be something like `Y,M,V,..`. If a table has an ID only, you can fake it with a view based on the `Type.` For example if MySpace and Vimeo tables have some specific columns, but YouTube has an ID only, just make a `YouTube view` to "fake" a table.
Damir Sudarevic
(...continued) I have simply anticipated that each ID is somehow data-type different and that each service would have some specific columns.
Damir Sudarevic
@Damir thanks, one more question, how would you store the embed codes? all I can think to do is take the embed html and add '<php echo $var1; ?> where the id's go then store it in the db and use Eval to excecute it.... is there a better way?
Mark
If you are referring to `<object><embed></embed></object>`, I would put those into a `nvarchar(); varchar unicode`
Damir Sudarevic
yes, but how would I get the variables into the embed code to display?
Mark
the only ways I can think of is insert a strange combination of characters to act as a marker to be replaced in php by the id's or to insert php and then EVAL it.
Mark
Not sure what would be optimum for that one, but with few experiments you should be able to nail it. I'm more a DB type of a guy.
Damir Sudarevic
thanks anyway :)
Mark
A: 

So, here's what I'd do in such a situation: Setup your table with columns for your primary key and userid fields and anything else you may need to identify the user or application (maybe a 'mediatype' field). The rest, put into a VARCHAR field, make it large enough to hold lots of data. Not sure how much space you would need, but I'm going to venture a guess that you will need between 1K and 4K+ of space.

The reason for a VARCHAR field: you never know what other new fields you will need in the future. Let's say next year youtube adds another parameter, or a new media format comes along. If you model your database to represent all fields individually, you will create an application that is not scalable to future or other media formats. Such modeling is great when you're describing a system on paper, but not so good when you implement code.

So, now that you have a varchar field to store all your data in, you have several options for how to store the data:

  1. You can store the data as an XML document and parse it on input/output (But you will most likely need more than 4k of space), and you will incur the cost of parsing XML.

  2. You can store the data as whatever data format you may need for your application (serialized object for java, JSON for javascript, etc). If you're serializing an object, you may also need more than 4k of space, and a VARBINARY field, not VARCHAR.

  3. comma delimited string, although this fails if your strings contain commas. I probably would not recommend this.

  4. null delimited key/value pair strings, with a double null at the end. You will need a VARBINARY data field for this one.

Number 4 is my favorite, and something I would recommend. I've used this pattern for an existing web project, where my strings are stored in format of:

'uid=userid/0var1=value1/0val2=value2/0url=urltosite/0/0'

Works like a charm. I use the data to build dynamic web pages for my users. (My application is C though, so it deals well with parsing a character array).

Your application could use the data from your first columns (like 'mediatype') to execute specific parsing routines if required, and use the VARCHAR/VARBINARY fields as input. Scaling to new types of embeddable media would be as simple as writing a new (or extending an existing) parser and defining a new 'mediatype' value.

Hope this helps.

Mike Mytkowski