How to create relationship between tables? - php

I have one table for posting new articles and the content of the table is printed using a while loop.
Now I want the viewers to be able to comment on the article so I created another table for comments and a form under article in the while loop, but whenever anybody comments on the article the comment is showed with all the articles.
Because article and comments are in one while loop and there is no relationship between the tables.
tables are as follows:
content_posts(
id int primary auto,
subject varchar,
postby varchar,
date date,
content varchar
)
comments(
id int primary auto,
name varchar,
email varchar,
body varchar
)

If you want to set up a relationship you have to determine the sense of your relationship.
One to One
Each side of the relationship is related to one and only entity. For example, nowaday, you split up the users definition in two parts :
the connection handler (password, last login date, activation)
the profile info (username, email, favourite movie...)
One profile has only one handler and one handler has only one profile.
In that case each table has to be added with a foreign key that takes the identifier of each entity.
One to Many
The case that you have with your blog. One article has many comments, one comments has one and only one article.
So, in your comment table, you have to add your foreign key that is a link to your article.id.
Then to select the comment that are in one article, you have to make a WHERE :
SELECT * FROM comment_table WHERE id_article = 1 -- for your first article,
If you want to load info from your article table and your comment table, you have to use the JOIN command :
SELECT comment_table.*, article_table.* FROM article_table
JOIN comment_table ON article_table.id = comment_table.id_article
many to many
each entity can be associated to many of the other. For example, il you provide tags to your articles : each tag cas be assigned to many articles, each article can have many tags.
In this case, you have to create a new table which only have tag_id and article_id.
To select one article with his tags, you have to make a double join :
SELECT article.*, tags.* FROM article_table article
JOIN tags_in_article tia ON tia.id_article = article.id
JOIN tag_table tags ON tia.id_tag = tag.id
WHERE article.id = 1

You can try linking the tabels by the aticle id column: for example: ARTICLES with the column id and COMMENTS with a field named article_id which will contain the id of the corresponding article.
Then you can use an INNER JOIN like this
SELECT * FROM ARTICLES as t1 INNER JOIN COMMENTS as t2 ON t1.id = t2.article_id
Hope it helps!

You need to define primary key in your article table, normally called id, and a foreign key in your comments table. This key relationship, in this case a one to many, is then used to ensure only comments related to a specific article are displayed. Using the id you would loop through the foreign keys finding the matches.

Related

Get CSV from query which involves multiple tables

I'm trying to make a query to extract elements from 2 tables, which are linked via another table.
So I have 3 tables:
authors
- id, name, book
category
- id, name, description
category-author
- id, idauthor, idcategory
Now I want to make a query to make the following output:
row: authors.id, authors.name, authors.book, category.name
I don't know what category's are linked using the 2 tables only, so I need to use the last one, the category-author table. The id's of both the author and the category are linked via that table.
I got the following query:
SELECT authors.id, authors.name, authors.book, category.name FROM category, author LEFT JOIN SELECT ??
I'm stuck at the remaining part of the query.
Also when I have this query, can I just extract a CSV with phpmyadmin?
You can get related information from different tables using table joins. Relations between tables should be specified using foreign keys (i.e. the column idcategory from category-author is presumably a foreign key that refers to primary key column category.id). In a join clause, you merely specify which tables are to be joined and on what column:
SELECT table1.col1, table2.col2
FROM table1
JOIN table2 ON table1.pkCol = table2.fkCol
This means you can't specify any SELECT or FROM clauses within a JOIN clause. The columns you wish to select from joined tables are all specified in the initial SELECT statement, and you only specify one table in the FROM clause, from which you subsequently perform the table joins.
In your case, I think this should get you started:
SELECT authors.id, authors.name, authors.book, category.name
FROM category
LEFT JOIN category-author ON category-author.idcategory = category.id
LEFT JOIN authors ON authors.id = category-author.idauthor
I'm not sure how familiar you are with foreign keys, primary keys and table joins, so I won't elaborate any more on this. I think specifying multiple tables in a FROM clause is bad practice, even if your database system still supports it (Related question).
From then on, you can easily export the results from within PhpMyAdmin, as there is an export button for every table overview, including query results.

MySQL - Database design - separate tables for users and profile

From what I've been reading online, I understood that it's better to split the data into more tables, if possible because of the access times.
Right now I have a table in which I am storing usernames, passwords and join date
This is how my table looks:
'user'
'user_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
user_username VARCHAR(80) NOT NULL,
user_password VARCHAR(255) NOT NULL,
user_join_date INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (user_id) ');
I am trying to create a new table called profiles in which I want to store first name, last name, email, age and gender. What I think is that I need a one-to-one relationship, so I should be using the user_id but I'm not really sure how to implement it.
Should I create another table called profiles with
profiles
profiles_id
first_name
last_name
email
age
gender
and another one which should be the relationship ? e.g.
user_profiles
----------
user_id
profiles_id
Is this right? How would the SQL look for the user_profiles?
Thanks
Don't split the tables. Just add the new columns to your existing user table. You might find later on that splitting tables is a good idea based on actual queries and usage patterns but until you have that kind of data, keep things simple.
If you must create a profile table, don't create a user_profiles table. That would allow an m-to-n relationship which is probably not what you want. A simple user_id column in profiles is better. In fact, it could be both a foreign key and the primary key to make sure that each user row only have one and only one profile row (although by splitting the tables you might still have a user with no profile).
Usually, you create an association table, like user_profiles you have described when one user could have more than one profile, and/or one profile could belong to one or more user.
As you have said, here you have a one-to-one relationship between user and profile. So, you can simply add a user_id column to your profile table, and define it as a foreign key to user table.
Then, a simple JOIN will allow you to query both tables at the same time:
SELECT u.*, p.*
FROM user u
JOIN profile p ON u.user_id = p.user_id
Add a new field in the User table, ProfileId, and set it as Foreign Key (FK). Each time you create a User, you have to assign to it a profile (which will be the ProfileId PK from profile table).
If you want to see also the profile information of a user, you have to do a join
Select username, first_name,second_name
From user u, profile p
Where u.profileId = p.profileId
this
user_profiles
----------
user_id
profiles_id
is used in a many-to-many relationship. By example, you want to assign to an admin some privileges, but those privileges can be also assigned to more admins. Then, you have to create a 3rd table to solve this problem. Here is an example, but you don't need to do this.
You could add a user_id field to your profiles table and JOIN the tables on user_id.
SELECT user.user_username, ..., profiles.first_name, ...
FROM user
INNER JOIN profiles
ON user.user_id = profiles.user_id
This should fetch data combining information from those rows where the JOIN condition is met (i.e. user.user_id = profiles.user_id).
It is true that having more than one tables is a good idea. I am not sure what you mean about access time, but there are other advantages.
- Your users database containing passwords etc is "sacred", you never change its structure and you limit the rights to it (read, write) to the strict minimum.
- You can then have several "satelites" tables such as profiles, private messages, etc which are more flexible, less sensitive and which you can change all the time.
About your question per se, there is no need for a separate table with the relationships. In fact is a very bad idea which will complicate your queries and doesn't have any advantage. Instead, in your profiles database you will have one column that refers back to the user id.
users
--------
id
user_name
email
password
users_profiles
---------
id
user_id
favourite_animal
Table user
user_id |user_username |user_password |user_join_date |profile_id
Table profile
profile_id |first name |last name |email |age |gender
When selecting a user by user id:
SELECT u.*, p.* FROM user AS u INNER JOIN `profile` AS p ON u.profile_id = p.profile_id WHERE u.user_id = 1
But a user should only one gender, one age, one name and surname. Maybe e-mail adresses might be many. I suggest you there is no need to join tables which have a 1-to-1 relation. Instead merge those tables.

Organizing a Database

In my application I have 2 tables in the DB (MySQL):
Companies and News. Company has many News.
Company can have a set of pictures which will be displayed on the company "view page" alongside with all relative information about this company.
I've added a Photos table with next fields: id company_id filename
My question is: Now I also need to have pictures which will belong to News.
I should add another table, which will be called for example Media or I should add additional field (type) to my Photos table, rename company_id to foreign_id and then filter results in PHP and build more complex queries with for example AND 'type' = 1 to fetch photos related to Company and 'type = 2' to fetch photos related to news.
What is a better approach?
You should take the company_id field out of the Photos table and create two new tables, CompanyPhotos with id, photo_id, company_id fields, and another NewsPhotos with id, photo_id, news_id.
Then if you want to get the photos for a company you can do: select * from Photos p inner join CompanyPhoto cp on p.id = cp.photo_id where cp.company_id = ?.
And similary with NewsPhoto: select * from Photos p inner join NewsPhoto np on p.id = np.photo_id where np.news_id = ?.
It is always good to normalize databases. In the beginning it was just about tables with all data and it has evoluted to linked tables with common fields.
Hence, I strongly recommend you to have the table Photos.
After all, you have to make the basic question: can a photo belong to different news? Can a news have different pictures? If both questions' answer is "yes", you have a N:M relation, which is resolved with a middle table containing an id from every table.
You could use UUIDs as your primary key. Because they are unique application-wide (if you create them with CakePHP), you could just use a parent_id column in your Photos table and get rid of the type colum.
Another approach would be MySQL Views. You could setup 2 Views (e.g. NewsPhotos, CompanyPhotos) on top of the Photos table. CakePHP handles (simple) Views like tables, so you could create easily Models & Controllers for this.

PHP Which Join Statement to use when trying to grab data from another table

I'm trying to figure out the best approach, more specifically which JOIN to use, with my current situation:
I have two tables (entries, users) in my database. I'm querying and displaying all my news entries on one of my pages. With each entry, I'm also posting the entry information such as date, time and the author (or user) who created the entry.
In my "entries" table, I'm only inputting the user's id (user_id) as the post's author. The "users" table has all the author's information, such as name, email, etc.
Which "JOIN" statement would be best for specifically querying the "entries" table to display all my entries but to also grab certain information from my "users" table just by matching the user_id from "entries" to user_id in "users"?
Simple join statment
SELECT e.*,u.* FROM entries e JOIN users u
ON e.user_id = u.user.id
LEFT INNER JOIN probably.
it will display all from entries, and if users is atached to entries will be dispplayed aswell, else the field will be null.

Linking tables in mysql

I need to know how to link two tables in a php/mysql set up then rank the results?
Here is my situation.
I have a stories table:
storyid
writerid
title
story
submitdate
and a votes table
voteid
userid
storyid
vote
I store a vote up as a 1 and a vote down as a -1
I am looking for a way to join these two table then rank/sort the stories by the number of votes they recieve.
I am open to any ideas about how to do so or a different possible database schema.
I prefer to keep the names of my tables singular. It's not a "Stories" table; it's a "Story" table with multiple rows.
A vote can only be attributed to a single story, so it's a one-to-many relationship between the two. I'd put the foreign key in the votes table and let it point out the story it's associated with. Change your schema if you agree: remove the voteid from the story table and make storyid in vote a foreign key to the story table.
But with that said, perhaps you can try a query like this:
select stories.storyid, sum(vote=-1) as down, sum(vote=1) as up
from stories
inner join votes on (stories.storyid = votes.storyid)
group by stories.storyid
Corrected per ypercube's comment below.

Categories