i wanna make a project to find a rented house / room
user can post his room/house to rent
and others can see it on the map
first user should login then he register his location in table location.
table location consist id_location, lat, lng, id_user, etc.
id_location is auto increment,its primary key.
id_user is from session that user logged on, it reads that username, Its foreign key.
rest are input by user,
i've succeed to make till this point
and the next thing is user gonna pick house or room to rent
example; they wanna rent a room.
this room table has id_room, id_user,id_location, rate, etc.
id_room is auto increment, primary key.
id_user is from session that user logged on, so it reads the username.
and the problem is for the id_location.
how can the database had that id_location from the last location input / location tbl?
Because that a location can have more than 1 room and the type of the room can be different, like it rate, facility, or etc.
so i make it several input for each room,
then user can creates its own room data for each room but has a same id_location
i mean something like
insert into tbl_room
values (null, '$_SESSION[username]', '$rate','$bla' ,'...','...' ,'...' , )
where id_location from location.id_location
but i know 'where' cant be in input scenario ..
i've read something about select statement
but i dont know how that select works in my case, i mean the exact query will be
i hope u r understand about my problem
thanks be4
On this case you have a one to many relationship, where one location can have many rooms. The simple solution is to have a column on the rooms table that references the location id from the location the room belongs to.
You can make something like this on MySQL
Create table locations (
Id int auto_increment,
Location varchar(100)
)
Create table rooms (
Id int auto_increment,
Location_id int
)
ALTER TABLE rooms ADD CONSTRAINT fk_location
FOREIGN KEY ( location_id` ) REFERENCES locations (id)
Insertions would be similar to this:
Insert into room (location_id) values ({$locationId});
And then you can get the room location by something like
Select l.location
From location l
Inner join rooms r on r .id_location = l.id
Where r.id = {$roomId}
Related
I am developing a reservation system for my school project. It is based on PHP and MYSQL.
The system allows a user to register. After successful login, the users can make a reservation which is stored in the following table in phpmyadmin.
User Table
When a user registers, he gets a user_id. When a user makes a reservation, the data is inserted into the table against the same user_id. But when the user tries to make another reservation, there is no way to store the information of the next reservation.
The question is how do I allow the user to make several reservations?
The user_id is my primary key so I understand it is not possible to create multiple records against one primary key.
Do I have to create a new reservation table and link it to user_id through a Foreign key relationship>? But if my reservation table has a primary key, then several records cannot be inserted against one primary key.
Somehow, each reservation must be linked the unique user_id so that the user can check all the bookings under his name.
Each reservation also needs a unique ID which can be used to cancel/update the reservation.
I believe it must be a basic MySQL question. Something like creating a new reservation table and connecting it with user_ID but I am unable to think of a concrete solution.
Your help is very much appreciated.
Thank You.
Make table users
then at least 2 fields id, name
then make table reservations and its One-To-Many relation so you need to put foreign key in reservation(many side)
reservation
id, name, user_id
then to get reservations from user 1 use select with join
SELECT * FROM reservations r JOIN user u ON r.user_id = u.id WHERE u.id = 1
Lately i found myself designing a database. The database is consisted of several tables (InnoDB) :
Table 1: Country (id , country_name)
Table 2: City (id, city_name , countryid)
Table 3: Users (id , cityid , A , B, C, D, E)
On the Users table, A , B ,C , D and E are some characteristics of the user, where characteristic A if you combine it with cityid must be unique, that is why i created a unique index for these 2 columns:
CREATE UNIQUE INDEX idx_user ON Users(cityid , A);
The rest columns B,C,D and E are other user characteristics (for example hair color, height, weight, etc.), that as you understand, will be repeated on the table ( hair color = black, or weight = 75 kg).
At the same time countryid and cityid are configured as foreign keys on UPDATE and DELETE CASCADE.
Search will be based on cityid and A columns. A drop down menu to select the city (hence cityid) and a text box to insert the characteristic A and then hit SEARCH button.
My questions are:
On Users table, i have repeating data in the same column (columns B, C ,D and E). This is against 2NF. Do i have to create a separate table for each of these columns and then assign a foreign key of each of these tables to Users table in order to achieve 2NF?
Table B (id, Bchar)
Table C (id, Cchar)
Table D (id, Dchar)
Table E (id, Echar)
Users (id, cityid, A, Bid, Cid, Did, Eid)
For the time i will not use columns B,C,D and E as search data, only display them after searching using cityid and A search. If (in the future) i decide that i need to display all results of Users that live in cityid and have black hair, what do i have to keep in mind now while designing the database?
In one hand we have DML(INSERT, UPDATE, DELETE) and on the other hand quering (SELECT). DML will work faster on normalized DBs and quering on denormalized DBs. Is there a middle solution?
Will UNIQUE INDEX created above , be enough to ensure uniqueness for the combination of the data in columns cityid and A? Do i need to further restrict it using JavaScript or better PHP?
Multiple Queries VS Joins:
Normalizing the database will require multiple queries or a single query with joins. In the case where "The user searches for a user from Madrid with characteristic A":
a) Multiple queries:
i) Go to City table and find the id of Madrid (for example, id = 2 )
ii) Given the Madrid id and the input for characteristic A, go to Users table and SELECT * FROM Users WHERE cityid="2" AND A="characteristic";
b) INNER JOIN:
i) SELECT City.city_name, Users.B, Users.C FROM City INNER JOIN Users ON Users.cityid = City.id;
Which one should i prefer?
Thanks in advance.
Your tables are already in 2NF.The condition for 2NF is there should be no partial dependency.For example lets take your users table and user-id is the primary key and another primary key more appropriate to call candidate key is (cityid,A) with which you can uniquely represent a row in the table.Your table is not in 2NF if cityid or A alone is enough to uniquely retrieve B,C,D or E but in your case one needs both (cityid,A) to retrieve a unique record and hence it's already normalized.
Note:
Your tables are not in 3NF.The condition for 3NF is no transitive dependency.Let's take the users table here userid is the primary key and you can get a unique (cityid,A) pair with that and in turn you can get a unique (B,C,D,E) record with (cityid,A) obtained from userid.In short if A->B and B->C indirectly A->C which is called transitive dependency and it's present in your user table and hence it's not a suitable candidate for 3NF.
I'm designing a website in which you can upload games with a description, etc, and store their rating. I am the only one who can provide a rating, so I won't need a second DB for that.
However, there will be indefinite rounds of competitions, so I want to store the Round # in a column in the DataBase. The other requirement is that each round has it's own information, so I'll be making a second table with a Round_Number, then other fields like Description, Due Date, etc.
So this is my current DB schema idea:
Entries ( Comp #, Entry # AutoInc, Password,
Entry Date, Author Contact, Description, Screenshot, Website )
Competitions ( Comp #, Theme, Entries, Start Date, Finish Date, Prize )
So Entries can left join Competitions on Comp # to get extra information about its competition. Does these seem most efficient? There is no account system (or users table), each entry just gets its own password for editing.
I would think this through further. You could potentially have different screenshots for different Entries and competitions. You might as well define a relational schema and add user accounts for authentication purposes. Define three tables:
CREATE TABLE USERS_T
(
account_id number,
username varchar,
password data_type,
author varchar,
....
)
CREATE TABLE COMPETITIONS_T
(
comp_id number,
description varchar,
theme varchar,
#entries number- not needed, just count by id in ENTRIES_T table
start_date date,
finish_date date,
prize varchar,
...
)
CREATE TABLE ENTRIES_T
(
account_id number,
comp_id number,
entry_date date,
descr varchar,
screenshot blob,
website varchar,
...
)
Each competition can have multiple entries, but each entry can only be for 1 competition.
Add a primary key on the ENTRIES_T table: PRIMARY KEY (account_id, comp_id)
You could even take this further, define a themes table, comments table, etc. I think you'll get the idea. Hope this helps. Goodluck!
Ok so a user comes to my web application and gets points and the like for activity, sort of similar (but not as complex) as this site. They can vote, comment, submit, favorite, vote for comments, write description etc and so on.
At the moment I store a user action in a table against a date like so
Table user_actions
action_id - PK AI int
user_id - PK int
action_type - varchar(20)
date_of_action - datetime
So for example if a user comes along and leaves a comment or votes on a comment, then the rows would look something like this
action_id = 4
user_id = 25
action_type = 'new_comment'
date_of_action = '2011-11-21 14:12:12';
action_id = 4
user_id = 25
action_type = 'user_comment_vote'
date_of_action = '2011-12-01 14:12:12';
All good I hear you say, but not quite, remember that these rows would reside in the user_actions table which is a different table to the ones in which the comments and user comment votes are stored in.
So how do I know what comment links to what row in the user_actions?
Well I could just link to the unique comment_id in the comments table to a new column, called target_primary_key in the user_actions table?
Nope. Can't do that because the action could equally have been a user_comment_vote which has a composite key (double key)?
So the thought I am left with is, do I just add the primary keys in a column and comma deliminate them and let PHP parse it out?
So taking the example above, the lines below show how I would store the target primary keys
new_comment
target_primary_keys - 12 // the unique comment_id from the comments table
user_comment_vote
target_primary_keys - 22,12 // the unique comment_id from the comments table
So basically a user makes an action, the user_actions is updated and so is the specific table, but how do I link the two while still allowing for multiple keys?
Has anyone had experience with storing user activity before?
Any thoughts are welcome, no wrong answers here.
You do not need a user actions table.
To calculate the "score" you can run one query over multiple tables and multiply the count of matching comments, ratings etc. with a multiplier (25 points for a comment, 10 for a rating, ...).
To speed up your page you can store the total score in an extra table or the user table and refresh the total score with triggers if the score changes.
If you want to display the number of ratings or comments you can do the same.
Get the details from the existing tables and store the total number of comments and ratings in an extra table.
The simplest answer is to just use another table, which can contain multiple matches for any key and allow great indexing options:
create table users_to_actions (
user_id int(20) not null,
action_id int(20) not null,
action_type varchar(25) not null,
category_or_other_criteria ...
);
create index(uta_u_a) on users_to_actions(user_id, action_id);
To expand on this a bit, you would then select items by joining them with this table:
select
*
from
users_to_actions as uta join comments as c using(action_id)
where
uta.action_type = 'comment' and user_id = 25
order by
c.post_date
Or maybe a nested query depending on your needs:
select * from users where user_id in(
select
user_id
from
users_to_actions
where
uta.action_type = 'comment'
);
On my website, I have a table movies and a table users
I'm trying to have an "Add to favs" button that a user can click, which will add that movie to his favorites (ajax / javascript not necessary at the moment, just php).
So what's the simplest way I could do something like that? I've thought about this but I can't seem to find a solution (all I think of is way too complicated, and in my opinion not possible).
What's your thoughts?
I don't need a ready-made script, just an idea that could get me working (although if you have an example of such script, I'd be happy to look at it).
Thanks!
This is a many-to-many relationship. A user can favorite many movies, and a movie can be favored by many users. In an RDBMS, you represent a many-to-many relationship with a third table. I call this an intersection table but it goes by other names too.
Create a table with two columns. The columns are both foreign keys, referencing movies and users, respectively.
CREATE TABLE Favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
When a user chooses to favorite a movie:
INSERT INTO Favorites (user_id, movie_id) VALUES (?, ?)
When a user decides they don't like a movie any longer, delete the corresponding row:
DELETE FROM Favorites WHERE (user_id, movie_id) = (?, ?)
To get the set of movies favored by a given user:
SELECT movie_id FROM Favorites WHERE user_id = ?
To get the set of users who favor a given movie:
SELECT user_id FROM Favorites WHERE movie_id = ?
Regarding one of your comments:
You shouldn't make the "Add to favorite" a link. Indexers like Google will follow links, and then before you know it, every user has favorited every movie.
The general best practice is that read-only operations can be GET requests, while operations that write to the database can be POST requests. This means that you need to use a <form> element to submit POST requests, not an <a href="..."> element.
Add a third table:
CREATE TABLE user_favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY user_id REFERENCES users (user_id),
FOREIGN KEY movie_id REFERENCES movies (movie_id)
)
This is called an intersection table or join table, as it joins rows in the users table to rows in the movies table (as you see, each column is a foreign key). It is also defines a many-to-many relationship, because one user can like many movies and one movie can be liked by many users.
When you go to add a favorite movie for a user, all you have to do is insert a row in this table with the ID of the user and the ID of the movie:
INSERT INTO user_favorites(user_id, movie_id) VALUES([user ID], [movie ID])
To see what movies a user has favorited:
SELECT movie_id FROM user_favorites WHERE user_id = [user ID]
You will need to create a new table:
user_favorite_movies
--------------------
ID (primary key)
userID (foreign key)
movieID (foreign key)
date
Then when the user clicks the 'Add Favorite' button, you just insert a new row into user_favorite_movies with the users ID from the user table, the movie id from the movie table, and the date it was added (good for sorting later).
Hope this helps!
Best,
-Eric
You could create a table favourites with three columns, id, mid and uid. To add a favourite:
INSERT INTO favourites (mid, uid) VALUES (3, 5)
To search for favourites of one user:
SELECT * FROM favourites WHERE uid = 7
To search for people who favourited one movie:
SELECT * FROM favourites WHERE mid = 9
So far as I can see, you'll still need to use JavaScript or Ajax to do the post, unless you want to refresh the page every time thet mark/unmark a favorite, and also to add/remove the new favorite indicator in place at the same time.
Or am I missing something?