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.
Related
I have an idea where a user can upload a maximum of 5 images for his or her gallery and can select one of them as his or her profile pic. Is it possible to save the names of all 5 pics in a single column, say, image? Or do I have to make 5 separate columns for storing these file names?
As an example, I could create a column called images and store values in this manner:
{"129cc68678d1e67d18d49d93cec040ce":{"filename":"129cc68678d1e67d18d49d93cec040ce.jpg"},"97ac1e22ea3fd6f02362233d8147ecb5":{"filename":"97ac1e22ea3fd6f02362233d8147ecb5.jpg","primary":true},"eeb239b4edff7e1a09246d38977a5646":{"filename":"eeb239b4edff7e1a09246d38977a5646.jpg"},"55a3810c1b0eaee039c753c12dccbc38":{"filename":"55a3810c1b0eaee039c753c12dccbc38.jpg"}}
Primary:true implies that it's a featured image/ profile picture.
Both of your proposals --- 5 pieces of information in one column and 5 columns --- are bad ideas. What if you ever want to change the limit to 4, or 6, or 20?
Normalize your data instead. Create a table for the images and another for the user-image relationships. In that second table, set a flag for the profile picture.
What you will want to do instead, is create another table to hold your image filenames. Your galleries table would hold an ID and the other info you are storing for the gallery, then your images table would have three columns. One for its ID, one for the filename, and one to store the ID of the gallery it belongs to (called a foreign key).
So i have an idea how to implement my gallery on my website, but need help from someone experienced to see if it's OK or not.
So basically the idea is that when a moderator uploads a few images to an existing article, i would rename those images in something like [ name of the article + 8 random numbers ] just in case there are no duplicates. When i generate the new name, then the system will save it in a specific folder. And after that I append each name of an image on to an array which I later save in a database single column for that article in question. But each name is divided with a comma.
So my question is, would this be an OK solution? Never done this kind a thing so would really appreciate some sort of guidance.
EDIT 1:
Ok the idea goes like this:
Moderator wants to add images to an existing article, he chooses the images, and uploads them for this example lets say there are 5 images.
After the upload is completed the PHP code changes the names of the images uploaded to [article_name]+[random number, length 8]
after that i plan to put the new names in an array like this:
array(image1,image2,image3,image4,image5);
After that it's only a matter of saving it to the DB and when needed i have the name of the images to be used in the gallery.
EDIT 2:
For saving I intend to use the implode function.
After saving it later for the gallery I can easily use the explode function to get every name out of the string.
You should not implode the array and save it in one single field in the database. Instead you should create a new table like
CREATE TABLE article_images
id int(11) PRIMARY KEY AUTO_INCREMENT,
article_id int(11) INDEX,
...
);
This table "links" back to the article-table with the column article_id so you can find out which images belong to which article.
How you save your images is up to you. You can indeed use some approach like you propose. I think I would go a different way like creating folders for every article-id and inside create the images based on their id of the corresponding row in article_images, like
/
123/
5.png
456/
6.jpg
where 123 and 456 are article-ids and 5 and 6 are ids of rows in article_images. But this is just my proposal. There exist lots of different ways, which are all more or less good and secure.
I'm building a website in PHP to share my comics. I'd like to implement categorization to allow people to filter which comics they'd like to see.
I've asked this question before, but at that time my site's architecture was not using a database.I've since implemented a database (which is amazing, btw) so I need to change things up.
I'm thinking the way to do this is:
1) Make 2 tables: 1 for categories, 1 for images
2) Insert images into their respective tables based on which filesystem folder they're in and assign that table id
3) Insert all images into All_Images table with their newly assigned category id
4) Take in user input to decide which images to show. So, if user input = cat 1, then show images with category 1 id.
So, basically I need a way to initially assign categories to the images when they come in from the filesystem. Is there an easier way to do this? Do I have to create multiple tables?
Any thoughts on this?
Thanks!!
The normal way would be to have an images table (presumably with filenames rather than the actual images?) and then a one-to-many relationship to categories so that each comic can have more than one:
Table:Image
-----------
rowid: integer identity
displayname: varchar
filename: varchar
Table:Category
--------------
rowid: integer identity
displayname: varchar
Table:ImageCategoryLink
-----------------------
imageid: integer foreign key references Image:rowid
categoryid: integer foreign key references Category:rowid
Clear?
One table category with id and name etc, one table for image with id src name etc.
Two choices after that :
If an image has one and only one category, put a field id_category in table image
If an image can has several categories make another table image_category with id_image and id_category
Since you are a beginner (no offence) and I don't think there will be millions or cartoons in the table. Use a SET field (or ENUM if your cartoon can only have one category) for you categories.
There are people who will vote this down since there are some negative side effects of using this (mainly when you want to change the categories). But with a relative small table this will not have any effect.
This will be the easiest solution. If you expect the site to grow big, use a second table for your categories and join the tables.
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 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.