Inserting an entry in multiple tables in an sql database - php

I'm creating a game in actionscript that requires the use of an external database to store user details and scores.
This database will contain multiple tables, currently there are two.
My first table contains the headers - ID, email, username, password.
My second table contains the headers - ID, lvl1Score, lvl2Score, lvl3Score.
In my game, when a new user is created it creates an entry in the first table with the ID auto-incrementing.
My question is - Is there anyway to automatically create an entry in my second table with its default values and the same ID when I add to my first table?
I've read about joins, but everything i've read just talks about looking up data over multiple tables.
Also, is my table structure correct in the sence that the ID value can be used using the JOIN keywork to look up an entry from both tables.

I would suggest you to go for triggers.
create or replace trigger trigger_name after
insert on table1
for each row
begin
insert into table2 values(new.id,"value for lvl2score","value for lvl3score");
end
Something like this.

If the tables truly have a one-to-one relation, I would recommend that you simply make one table having all the fields.
Or did you mean this should store multiple scores for each individual user? In this case, you should not insert a default record for the user. Instead, the score.ID field should instead reference user.ID and allow duplicates.

I suggest you to use triggers and for more flexibility create a many-many relationship between "user" and "level", so you will end up with 3 tables:
user
level
user_level (this will contain the foreign keys: user_id, level_id)

Related

Can you make/insert tables inside every row in a table of a database in PHP/MySQL?

Is it possible? If yes, how?
I am using xampp for my database and I wanted to make a database with "students" table, only one column for the list of student IDs, and every student ID has another table inside. (I was considering making tables for every student ID so that it can be done directly but it seems that it PHP/MySQL does not allow integers as table name).
No, you cannot put tables inside a row in SQL. That's not compatible with the concept of a relational database. What you can do is provide a foreign key to another table where you can collect the data you need to link to your first table.
What you need is to have one table with all you want about the students, and add a field with their ID.
So, yo don't have to get the information from student #123 as
SELECT * FROM 123
but
SELECT * FROM students_table WHERE IdStudent = 123

Insert INTO queries using WHERE clause

I have issue on INSERT INTO query,
In the registration form, when user enter username and select the department/center as bursary,
I want to insert that UserName into table bursary.
What I tried is;
$query14 = "INSERT INTO bursary (UserName) VALUES
('$UserName') WHERE DepartCent='Bursary'";
$result14=mysql_query($query14);
My table name is bursary, and it's look like ;
UserID UserName
1 ( ) <---- I want only UserName that choose department/center as bursary
Please anyone help me to solve this, appreciate that.
INSERT queries imply adding data that isn't there already. If you want to insert a value derived from a query you need to use an actual query to get it. The WHERE clause fails because there no row to examine until you insert one.
There's really not enough info to figure out what you're trying to do, but if we just go on this part of your question:
"I want only UserName that choose department/center as bursary"
Then you are probably looking for an INSERT..SELECT (assumes you have already inserted the data into some other user table 'your_user_table')
INSERT INTO bursary(UserName)
SELECT UserName from your_user_table
WHERE DepartCent='Bursary';
You can either:
insert new rows in a database table
update existing rows in a database table
Only when you are trying to change values of existing rows does it make sense to specify a WHERE clause to let the database know which values you want to change.
EDIT: Could you explain again what it is exactly that you are trying to achieve? Do you want to insert only some users filling out your form? Namely those that choose bursary as their department?
Why don't you change your table structure to something like:
Table DEPARTMENT:
Department Name, Department ID
Table USER:
User Name, Department ID (foreign key to Department)
EDIT Nr. 2: The way to do that is by normalizing your Table structure. Suppose one of the following things happened:
You want to add an additional department later on - you would not want to create a new table for that every time.
You want to change the name of a department - do you want to rename your tables? change your code,... I doubt that
So the way to go is to design your tables in a way that they separate the different "things" in your program. One type of thing you are working with are departments (bursary,...) another type of thing are Users. As a rough starting point try to make a table for each and try to connect the tables with so called foreign keys. Read it like this:
Every department has a unique department ID
Every User is associated to a department by this users Department-ID
You can then later on join these tables to find out all users of department X,...
Select u.userName,d.departmentName from User u INNER JOIN Department d ON
u.departmentId=d.departmentId
This would show you the names of all your users and their associated departmentName

Populating a third table to maintain efficiency

I am currently working on a PHP/MySQL project for an assignment. In studying the efficient design of databases while working on the assignment I notice that in many cases it is good practice to create a third table when working with only two sets of data.
For example, if we have a table for "Students" and a table for "Addresses" it appears to be a good idea to create a third table i.e. "Student_Addresses" since a student can hypothetically have more than one address (separated parents etc.) and a single address can represent more than one student (siblings).
My question is: How do we go about populating that third table? Is there a way that it is done automatically using primary and/or foreign keys?
I've tried Google and my textbook to understand this but I've gotten nowhere. Links to tutorials or articles would be greatly appreciated.
Thanks for your help. I hope the question and example are clear.
n:m or 1:m normalization rule
Option 1:
user table
id
f_name
s_name
......
user address table
id
user_id // this should be index only as foreign keys will allow 1:1 only
address line 1
address line 2
address line 3
address_type (home, office ....)
Option 2:
user table
id
f_name
s_name
......
address table
id
address line 1
address line 2
address line 3
address_type (home, office ....)
user_address table
userId
addressId
according to your description option 2 would be the right solution. After adding the data to user table and address table then you need to add the data to user_address table manually. Some Object relational mapper (ORM) may do add the data to the third table automatically but you need to define the relations. check http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html.
http://docstore.mik.ua/orelly/linux/sql/ch02_02.htm
http://www.keithjbrown.co.uk/vworks/mysql/mysql_p7.php
You can save the data in the third table using triggers when the data is inserted/updated/deleted in your base tables. You can learn more about triggers at
mySQL Triggers
However in your case it would be better if you could write the logic at the application/code level to make an entry in the third table. You can set up foreign key relationships to this table from your base tables so that the data remains consistent.
There is no native method in MySQL to populate Student_Addresses in your situation - you have to take care of entering data (connections) by yourself, but you can use - for example - transactions - see answers in this topic: SQL Server: Is it possible to insert into two tables at the same time?
For taking care of connections consistency - in Student_Addresses make not-null fields for relations to ID from Student and ID from Address, make both of these field as unique key together and use ON UPDATE CASCADE and ON DELETE CASCADE. This will take care of removing records from junction table when removing records from any of two other tables and also won't allow you to add same address to the same student twice.
I don't think data will be populated automatically rather it's responsibility of user to insert data.
I am note sure about PHP but using Hibernate and Java this can be done seemlessly. Since data of Students and addresses could be coming through some web application Hibernate can map java objects to records in table and also populate relationship table.

Issue in copying rows from one table to another

I am implementing a request mechanism where the user have to approve a request. For that i have implemented a temporary table and main table. Initially when the request is added the data will be inserted to the temporary table, on approval it will be copied to the main table.
The issue is there will be more than 5k rows to be moved to the main table after approval + another 3-5 row for each row in the detail table (stores the details).
My current implementation is like this
//Get the rows from temporary table (batch_temp)
//Loop through the data
//Insert the data to the main table (batch_main) and return the id
//Get the details row from the temporary detail table (batch_temp_detail) using detail_tempid
//Loop through the data
//Insert the details to the detail table (batch_main_detail) with the main table id amount_id
//End Loop
//End Loop
But this implementation would take atleast 20k queries. Is there any better ways to implement the same.
I tried to create a sqlfiddle but was unable to create one. So i have pasted the query in pgsql.privatepaste.com
I'm sorry that I'm not familiar with PostgreSQL. My solution is in MySQL, I hope it can help since if they (MySQL & PostgreSQL) are same.
First, we should add 1 more field into your batch_main table to track the origin batch_temp record for each batch_main record.
ALTER TABLE `batch_main`
ADD COLUMN tempid bigint;
Then, on approval, we will insert 5k rows by 1 query:
INSERT INTO batch_main
(batchid, userid, amount, tempid)
SELECT batchid, userid, amount, amount_id FROM batch_temp;
So, with each new batch_main record we have its origin batch_temp record's id. Then, insert the detail records
INSERT INTO `batch_main_detail`
(detail_amount, detail_mainid)
SELECT
btd.detail_amount, bm.amount_id
FROM
batch_temp_detail `btd`
INNER JOIN batch_main `bm` ON btd.detail_tempid = bm.tempid
Done!
P/S:
I'm confuse a bit about the way you name your fields, and since I do not know about PostgreSQL and by looking into your syntax, can you use same sequence for primary key of both table batch_temp & batch_main? If you can, it's no need to add 1 more field.
Hope this help,
Simply need to update your Schema. Instead of having two tables: one main and one temporary, you should have all the data in main table, but have a flag which indicates whether a certain record is approved or no. Initially it will be set to false, and once approved it will simply be set to true and then the data can display on your website etc. That way you will not need to write the data two times, or even have to move it from one table to another
You haven't specified RDBMS you are using, but good old INSERT with SELECT in it must do the trick in one command:
insert main (field1,...,fieldN) select field1,...,fieldN from temporary

splitting data into multiple tables

I am building a employees page.
Some of the information goes into an 'employees' table but some of it goes into a 'availability' table that is referenced to the 'employee' table:
availability:
id / employeeid (unique id from employees table) / monday available / and on and on /
So I don't have that unique ID from the employees table until I create them.
Is it fine to do a query where I set the employee info and then a query to get the last created row in the employee table and then use the unique id from that to set the availability...
Or is that messy and should I have a create employee page and THEN a set availability page?
So basically I want to know if it is cleaner and 'better' coding to separate the two functions?
Adding to #Quassnoi's answer:
You would add the employee record, then use the MySQL LAST_INSERT_ID() function to find the autoincremented unique id for the employee record you added. You can then feed that value back into the availability INSERT statement.
More details are on the MySQL manual page at http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html
It's important that you not use a SELECT statement (e.g. SELECT MAX(employee.id)) since there might be other uses adding records as well. LAST_INSERT_ID() is specific to your connection
Of course create employee first, availability then.
If your tables are InnoDB, you can do it in a transaction so that you can rollback the whole update if something goes wrong.
Is it fine to do a query where I set
the employee info and then a query to
get the last created row in the
employee table and then use the unique
id from that to set the
availability...
Yes, that sounds OK. If you use an autoincrement column for employeeid, you can then use mysql_insert_id() or equivalent to retrieve that last inserted id safely. Don't do SELECT MAX(employeeid) FROM ...., because you might get problems when loads of people are using it concurrently.
You can easily get the last insered record via
mysql_insert_id()
After that, you can insert an availability record for the desired employee.
Note: I would choose a framework that takes care of these issues, like Symfony or Cake.
Using the "last created row" may not always work the way that you're expecting and may complicate things in the future if there's growth or if another programmer assumes the project. If I understand what you're looking for, you should instead have 3 tables. One table for employees, one table for availability, and a third table should be used to store unique records for the association. In the association table each row will have columns for : a unique ID, the employee id, the availability id.

Categories