How to structure a huge mysql database with many profiles - php

The question is how to structure a huge mysql database with for example 10.000 profiles.
Example1
1 Database
3 Database fields (field_profile, field_images, field_posts etc.)
field_profile 10.000 profiles with an id and the rest of the information.
field_images 150.000 images related to the id in database_profile.
field_images 350.000 posts related to the id in database_profile.
Slow searching but when i want to change something really easy.
Example2
1 Database
30.000 Database fields (field_profile_profile1, field_images_profile1, field_posts_profile1, field_profile_profile2, field_images_profile2, field_posts_profile2 etc..
field_profile_profile1 1 profile with information.
field_images_profile1 50
field_posts_profile1 3500
Fast searching but when i want to change something really difficult?!
Which example is the best or is there a better option?

I would go for normalization, according that your number of records are not even close to huge:
[table_profile]
profile_id
[table_image]
image_id
profile_id
[table_post]
post_id
profile_id

You should simply come up with table that if Field profile and field image is same for different post then
table profile
field_id field_profile field_image
table post
field_id field_post
Second option if field_profile , field_image is different every time then come up with single table .
table field
field profile field_image field_post
Try to store repeating data in different table and use id's whenever needed , it will decrease your data storage and increase speed of database access .

Related

Correct MySQL structure for storing user-based data

So I have a question, I'm hoping it isn't too subjective.
I have a blog-style website, so on the homepage articles are loaded alongside the date published, the user that posted it, etc. Basic data like this.
I store it in MySQL like so:
article_id username date content etc.
1 user1 2015-05-14 01:35:14 my content a
2 user2 2015-05-16 02:33:15 my content b
This way, I can display it using one query, where I retrieve the username, date, content, etc.
My question is. I want to allow users the option to change their username. There are two options I see for this.
Either I continue storing data as I do now, and manually update tables like this with user-related data to the new username. Or I store data by a user_id rather than username, and have an extra query for each article loaded to get the associated username from another user table.
Which is the correct approach?
I ask this because I assume there's a recommended practice for this situation? Is it normal to store data by username and update it, or to store by id to avoid having to do this - but at the cost of the overhead when querying data. I'm guessing it's possible to display the username for id-based data in just one query, but that would still take significantly longer?
Depends. Do you see there is a 1:1 relationship with Article:User if yes, then storing in a single table will probably suffice but generally an user will publish multiple articles which will make it a 1:* relationship and in which case you should create a separate table for UserDetailsd and have user_id as FOREIGN KEY in Article table probably.
You should create a users table, store user_id which would be incremental and a user_name. When showing the user name in your app, join to the users table and show the name from that table and it will always be current. This is the best practice if you wish to allow user name changes. Updating all usernames it the articles table is not recommended. This will also allow you to store other user related information such as email, join date, etc... without having to keep all that in the articles table.
Create a seperate table with all user-related information and alter your current table, so only content and article related stuff is included. That's what I'd suggest you
Make a separate table for users something like:
-------------------
user_id | user_name
-------------------
Where user_id should be PK.
And another table, lets say article should look like:
-----------------------------------------------
arcticle_id | date | content | etc. | user_id
-----------------------------------------------
Where article_id could be a PK and user_id would be the FK from users table, making a relationship which could be used in other tables as well.
You can create a table for users, and use a foreign key on field username, specifying the behavior on updates. Is something like this:
alter table posts add constraint fk_post_user foreign key (username) references users (name) on update cascade;
In this way, when you update a row on table users, all user names on table posts will be updated too.

Associate data to users

I've got a database in which there is some data like:
Data
id|number|page|
1 |------|----|
2 |------|----|
3 |------|----|
Let's try to explain what i want to do: I want that, for example, user "A" can access only Data 1 and 2, and NOT 3.
So, technically, I want to store some information in the user table that tells me which Data he can actually download.
Creating a MANY to MANY relation in another table would be ideal.
association
user_id, data_id
data
id, number, page
user
id

mySQL Database - Storing Multi-Criteria Ratings

I've been doing a lot of searching and reading about rating systems, but couldn't find a solution to what I'm trying to achieve...
I have a website where users, once logged in, can submit a product. Now I want other users to be able to rate those products according to 3 different criteria. I'm using php and mySQL databases to store all of the information which is working great, I'm just not sure how to incorporate the ratings now.
At the moment I have a PRODUCTS database, which holds various tables according to their category. Here's an example of a table:
TOASTERS
---
ID (auto-incrementing)
Brand
Set
Number
Name
Edition
Image (stores the location of the image the user uploads)
Any user can then rate that row of the table out of 10 for 3 criteria (Quality, Price, Aesthetic). The user average of each criteria is displayed on each product page but I would like to store each of the user's individual ratings so that I can show a short history of their ratings on their profile page. Or have a live feed of the latest user ratings on the homepage.
What I'm trying to do is quite a lot like awwwwards.com. (See bottom-right of page to see the livefeed I'm talking about)
Thanks in advance!
I think you should use single PRODUCTS table or at least create PRODUCTS table and emulate inheritance between it and category tables.
Having a table for each category can give some advantages if each category has some specific properties, but it can lead to neccesity of writing separate code to work with each table. Alternatively you can use two tables to store all custom properties 'vertically': PROPERTIES(propertyID,PropertyName), PROPVALUES(productID,propertyID,PropertyValue).
If you choose to have multiple tables and emulate inheritance, it can be achieved like this:
PRODUCTS
---
ID (auto-incrementing)
Brand
Set
Number
Name
Edition
Image
VoteCount <+
SumQuality +-updated by trigger
SumPrice |
SumAesthetic <+
TOASTERS
---
productID (PK and FK to PRODUCTS)
(toaster specific fields go here, if any)
Than you will be able to create table VOTES, referencing table PRODUCTS
VOTES
---
productID (FK to PRODUCTS)
userID (FK to USERS)
Quality
Price
Aesthetic
VoteDateTime
If it is true that overall product rating is queried much more often than voting history, as an optimization you can add fields VoteCount, AvgQuality, AvgPrice, AvgAesthetic to PRODUCTS table, as srdjans already supposed. You can update this extra fields by trigger on table VOTES or manually in PHP code.
Create separate table for storing user individual ratings (primary key, user id, product id and ratings). Create additional fields in "products" to store averages. Every time some user rates some product, you insert record in "ratings" table, then calculate averages again for given product, and update rows in products. Doing this you will have easy access to ratings, and also, you can analyse user individual ratings.
Ps - You may also wish to store how many users rated some product.

PHP: Categorizing images into database

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.

MySQL database structure for infinite items per user

I have a MySQL database with a growing number of users and each user has a list of items they want and of items they have - and each user has a specific ID
The current database was created some time ago and it currently has each users with a specific row in a WANT or HAVE table with 50 columns per row with the user id as the primary key and each item WANT or HAVE has a specific id number.
this currently limits the addition of 50 items per user and greatly complicates searches and other functions with the databases
When redoing the database - would it be viable to instead simply create a 2 column WANT and HAVE table with each row having the user ID and the Item ID. That way there is no 'theoretical' limit to items per user.
Each time a member loads the profile page - a list of their want and have items will then be compiled using a simple SELECT WHERE ID = ##### statement from the have or want table
Furthermore i would need to make comparisons of user to user item lists, most common items, user with most items, complete user searches for items that one user wants and the other user has... - blah blah
The amount of users will range from 5000 - 20000
and each user averages about 15 - 20 items
will this be a viable MySQL structure or do i have to rethink my strategy?
Thanks alot for your help!
This will certainly be a viable structure in mysql. It can handle very large amounts of data. When you build it though, make sure that you put proper indexes on the user/item IDs so that the queries will return nice and quick.
This is called a one to many relationship in database terms.
Table1 holds:
userName | ID
Table2 holds:
userID | ItemID
You simply put as many rows into the second table as you want.
In your case, I would probably structure the tables as this:
users
id | userName | otherFieldsAsNeeded
items
userID | itemID | needWantID
This way, you can either have a simple lookup for needWantID - for example 1 for Need, 2 for Want. But later down the track, you can add 3 for wishlist for example.
Edit: just make sure that you aren't storing your item information in table items just store the user relationship to the item. Have all the item information in a table (itemDetails for example) which holds your descriptions, prices and whatever else you want.
I would recommend 2 tables, a Wants table and a Have table. Each table would have a user_id and product_id. I think this is the most normalized and gives you "unlimited" items per user.
Or, you could have one table with a user_id, product_id, and type ('WANT' or 'HAVE'). I would probably go with option 1.
As you mentioned in your question, yes, it would make much more sense to have a separate tables for WANTs and HAVEs. These tables could have an Id column which would relate the row to the user, and a column that actually dictates what the WANT or HAVE item is. This method would allow for much more room to expand.
It should be noted that if you have a lot of of these rows, you may need to increase the capacity of your server in order to maintain quick queries. If you have millions of rows, they will have a great deal of strain on the server (depending on your setup).
What you're theorizing is a very legitimate database structure. For a many to many relationship (which is what you want), the only way I've seen this done is to, like you say, have a relationships table with user_id and item_it as the columns. You could expand on it, but that's the basic idea.
This design is much more flexible and allows for the infinite items per user that you want.
In order to handle wants and have, you could create two tables or you could just use one and have a third column which would hold just one byte, indicating whether the user/item match is a want or a need. Depending on the specifics of your projects, either would be a viable option.
So, what you would end up with is at least the following tables:
Table: users
Cols:
user_id
any other user info
Table: relationships
Cols:
user_id
item_id
type (1 byte/boolean)
Table: items
Cols:
item_id
any other item info
Hope that helps!

Categories