I’m using a relational MySQL database for a website where people can create online stories by uploading various media: audio clips, photos, videos, etc. The site will feature a login to a personal space where people can create, view and edit the stories. For this question, let’s say the database has 4 tables: memorybox (with meta info about the story, i.e.: title, date and description), audio, photos and video (the latter three have all the media connected to one story in the memorybox table — individual media files are linked to a story by a column with the memorybox ID).
I’m using PHP to select all the media associated with a story, and the story’s metadata, and exporting to an XML file. From the XML I’ll use jquery to display, first, the stories (some sort of icon, with the story title) and then, when the story icon is clicked, all of the media in a story view.
What I want is to associate all media files with only one story (and its metadata). My problem is that I can’t quite get the XML results I need, and am uncertain if the issue is with the query or with the database structure. I have tried to select all where the IDS match, but that gives me a long list of separate entries for each of the media files. I’ve also tried a LEFT JOIN to associate everything with a memorybox ID, but I still get multiple entries for one ID. I tried GROUP BY but that gave me only one row of media data.
Is there a query that can do this or do I need to rethink my database structure?
Thanks, Cheryl
judging from your question you haven’t wrapped your head around relational databases yet. Do you realize the difference between procedural code and object oriented programming? Going RealtionalDB is a step similar in magnitude.
Think datasets, always, even if that set contains of only one record. A table is a dataset, a query result is another, a view is one, a join is one that combines two.
As for your question:
I understand a story is composed of one record in the memorybox table and one or more records in any of the media tables.
For this, your table structure is pretty much ok. I imagine
table memoryboxes(id int, metadata varchar),table fotos(memorybox_id int, thefoto clob),table audios(memorybox_id int, theaudio club),table videos(memorybox_id int, thevideo clob).To get ‘the full story’ you best select from all these tables based on the memorybox_id. That means 4 queries (in one transaction for neatness) after each other. Build the xml from those resultsets.
As for joins:
A (left) join should behave exactly as you describe. It combines datasets based on a premise (ids being equal in your case). A left join allows records in the dataset ‘on the left’ to be produced even if there is no matching record in the dataset on ‘the right’. Think about it; this will give you all permutations of your datasets that match your predicate. Exactly what you describe.
As for group-bys:
A group by (by id I guess) will ‘roll’ a dataset up and as you will have noticed you were required to have the columns in that group-by query either in the group-by clause or in a so called aggregate function (count, min, max, …), meaning either they participated in the resulting grouping (think composite keys in tables) or their final value would be composed of all the data in the underlying dataset group.
Long story short: your db structure is fine, use 4 separate queries (in a transaction) to get the data out.
Next steps:
Try to read a bit more about joins and group-by later, when you want to write a query that lists the amount of associated media in a story for instance: