I have 4 tables ...
"content" - Master list of content like title, desc, and contentType
"albums" - Albums made up of several photos
"photos" - Individual photo entries
"photosLinks" - Links photos to album(s)
"tags" - Tags used for searching and finding content
Is it possible to retrieve the photos for the content query if the contentType == 'album' in one query/shot?
For the tags, I can do a simple GROUP_CONTACT() since all we need is the text of the word.
I am not sure of the best approach to handle if(an album) other than reading the result (from php) and then making another query to get the photos linked.
Any tips or advice will be appreciated.
Thanks!!
Thomas
It's possible, but you'd end up with duplicate rows. I.e. you could just join, but you'd end up with something like:
Artist Album Photo
Cowboy Mouth Are you with me? [[Front Cover]]
Cowboy Mouth Are you with me? [[Back Cover]]
If you want some way of associating more than one row in one table to a single row of the result, then I am not aware of a means of doing that. You could do something like store a serialized data structure for one of the photo lists, but that of course doesn't follow the RDBMS philosophy too well.
Related
I'm designing a blog database. I want posts to belong to any number of categories, including none (i.e. number of categories = 0, 1, 2, 3, ...).
I understand that the common way to design such a database (e.g. in Wordpress), is to have one table for posts, one table for categories, and one table for relationships, thus:
table relationships
column relationship id
column post id
column category id
But this means that to display a post, my script will have to make at least three database queries. This seems slow to me.
Which is why, in another blog, I had only one table for posts which included a varchar column for categories, in which I inserted a string with all the category names, which I parsed in PHP, thus
table posts
column post id
... (many other columns)
column categories
where column categories contained a string that might look like this:
apples,oranges,bananas
which I simply explode()ed in PHP.
Please explain why I should avoid the second method (one table, explode). There must be something wrong with it that I miss, because it is not commonly used in blog software.
Note:
There might still be a table listing categories, into which new categories are written when a post is created, and from which lists of categories are drawn to display them in, of example, the sidebar.
I expect there to be many more queries for posts than for posts-in-categories, which is why I don't worry much about querying the second database for posts from a certain category, which might be faster in the first database.
In second case you will get huge problems with finding post by some category.
For example, you write posts about programming languages and want to show all post about python, php, ruby, etc on separate pages ... but you can't write simple and quick request to database because you violates 1 normal form in your second database scheme.
JimL has already mentioned JOIN which allows to make 1 request and get all needed information from standard many-to-many relationship scheme with link table post2category
I should begin by adding that i'm not very familiar with SQL and database structures, i know the basics but don't think that's more than that. I am trying to build a functionality which is supposed to add an article with unknown amount of images. Each article will consist of 4 parts: title, image or multiple images, description and price. The confusing part here is that one article may have more than 1 image, as so far i've only known how to upload single image at a time.
How do i upload multiple images into database at a time?
As for the database i was thinking of going for the following structure: 2 tables, 1st - 'articles' and 2nd - 'images'. the idea was to first upload the image into 'images' with random 16 character hash name and then post in 'articles' all article fields with a hash reference on the end of the row.
Is this a valid solution or are there any other, more efficient ways?
You will want to place a reference to the article that the images belong to in the images table. Ensure they are the same data type. The article_id will need to be unique (primary key)
When it comes time to retrieve the data in your app you can simply pull the images out that correspond to that article.
Article
--------------------
article_id
article_title
article_descr
article_price
Image
--------------------
image_id
image_article (foreign key links to article_id)
image_path
...
You can get creative and use a image_seq_no to indicate what sequence the image would appear in the article or some reference to paragraph or location.
If one post has many comments, and the comments are essentially the same as posts (e.g. they have a title, pictures and audio etc.) should I create two tables or just one?
For example, if I only use one table I can have a parent_id column, so If it's not a reply to anything it would be null, otherwise, it would have the id of the parent post. On the other hand I can create a post table and a comments table. Comments can also reply back to other comment so this could get confusing quick.
*Post*
id
title
content
image
audio
parent_id
or,
*Post* *Comments*
id id
title title
content content
image author_id
audio post_id
author_id image
audio
What the second option would allow is creating indexes. Infact I won't even have to add author_id or post_id If I use indexes from the start will I?
What are you thoughts on this SO? Which would be more efficient? I thinking of using redbeanphp for this.
The second option would be better. When displaying a message board, you don't care about comments and looking them up by an indexed parent post id column is fast. Posts and comments will likely have different fields, so keeping them separate is correct. The parent id index for the first option would work fine, but conceptually, it's messy and you're basically creating an index to use on half or however many comments there are relative to posts.
As a rule in database-design: Tables are called entities, so each entity in your application should be separated and demonstrated by table. Here, although you regarded posts and comments each has the same kind of data but finally each of them is a separate entity so they should be separated in two tables. This behavior is not a personal opinion. It is basic rule that leads to more smooth application development.
I'm trying to create a small Web App to categorize certain type of YouTube videos, when users submits a video they will choose what categories this video falls under and they will tag it with ready-made tags, for example:
Video one - Category: Ad - Tags: cute, funny, has animal in it.
I'm trying to sketch my Database for that (I'm using MySQL), so far I have two ideas.
Idea 1:
Table Videos with ID and Category columns, another table Tags with ID and Tag columns while Videos.ID and Tags.ID are linked together. So when the user tries to filter search results by tags, the query will have more conditions (AND Tag = 'something' AND Tag = 'other thing').
Idea 2:
One table Videos with Category and Tags columns, tags are stored as a string separated by commas, when the user tries to filter search results by tags, the query will more conditions (AND Tags LIKE '%something%' AND Tags LIKE '% other thing%).
So the question is: Is there any better method? I already think that the 1st one is wasteful (Each video might have up to 40 ready-made tags) and the 2nd one is clumsy. If not, which one do you think is better?
Creating a additional table linking video id and tag id together is the correct solution. Filtering is done by creating additional INNER JOIN conditions. A comma separated list just won't do - it drastically limits your selection and query possibilities.
Idea 1 looks good. Creating a separate table for storing tags helps in selection.
I have a MYSQL database of photo galleries;
each row contains a field with the list of images included in that gallery, eg:
1,5,134,13,5
these are the IDs of the photos. The same image_id could be included in other galleries.
When I delete a photo, I need to remove the corresponding id from the galleries that contain it.
What's the best way to do this in PHP?
I thought of EXPLODEing the field into an array, remove the value and then IMPLODE back and update the DB, but I'm pretty sure there's a better way?
thanks,
Patrick
THANKS Galen & all.
I'm a newbie and don't know much (=anything) about normalization. if I understand correctly, you're suggesting to have 2 tables: 1 with all the info about the photo (eg, image_id, name, caption, etc..) and another table with just a list of galleries that use that photo, eg:
gallery_id | image_id
1 3
1 7
1 5
2 3
2 8
so by deleting from this table WHERE image_id=3, i would remove that photo from two galleries.
In this case, however, I would I manage the order of photos? Having a string allowed me to have an ordered list of photos.
This is the exact reason why you normalize your tables. Then you could just run the query
delete from images where image_id=5;
delete from imageXgallery where image_id=5;
Where the images table contains all the image info. The imageXgallery table just contains image to gallery references.
I suggest you read up on normalization and update your tables.
EDIT: To allow for image ordering add an order field in your imageXgallery table. When you retrieve your images from the table you can order by that column.
While there may be slightly faster and more elegant solutions, exploding, cutting out and gluing together again is a perfectly acceptable way in my opinion.
Edit: Of course, Galen is right. If you have the chance, change the structure.
As Galen said, you need to normalize. Instead of a tuple (row) like ("gallery_id", "photo_id_1, photo_id_2, ...") you will have multiple tuples each having one gallery_id and photo_id. Then by deleting the photo_id from that table will take care of your problem.
If you don't want to change your table structure, it's probably less expensive to do string operations than to convert the strings into an array and back again. Look into using either str_replace() or preg_replace() for that.
If you can change the database layout, I would do the following:
As each gallery can have multiple images and as each image can be in multiple gallery, you have a many-to-many relationship.
So you have 3 tables, the first one to hold the gallery, with a galleryId primary key and additional fields for gallery info (if galleries have names, for instance, a name field), then you have an image table, with an imageId and all the image information, and then you have third table with just two fields, galleryId and imageId.
So if image 5 has to go to gallery 7, you'd enter 7 and 5 into the relationship table.
to get all the images for gallery 7, you'd run something like
SELECT * FROM images i LEFT JOIN galleryImages gi ON gi.imageId = i.imageId WHERE gi.galleryId=7
with galleryImages being the relationship table.
Likewhise, to delete an image from a gallery, just delete the row in the relationship table.
One thing you might want to pay attention to is to check if there are still entries for an image in the relationship table when you remove it from a gallery. or in other words, check if the images is being used in any galleries, if not, remove the entry from the images table as well, otherwhise you might end up with a lot of garbage image entries that aren't even needed anymore.
hope this helps to clear some things up.