Creating single insert query for 3 tables in MySQL - mysql

I have three tables in a MySQL database, the tables are labeled address, employee, and login_info. address and employee have a one to one identifying relationship with a foreign key with login_info table. I would like to write a single sql query that would populate all three tables at the same and use the PK from the login_info table as the foreign key in both the employee and address table. How would I go about doing this, below are the column descriptions for the three tables I have. Thanks in advance for any help or suggestion.

You can try this structure, mate:
START TRANSACTION;
-- INSERT BLOCK FOR login_info
-- GET THE NEEDED KEY FROM login_info LAST INSERT
-- INSERT BLOCK FOR employee
-- INSERT BLOCK FOR address
COMMIT;
This is not the single-query answer you are expecting, but this may satisfy your need for your module. Using MySQL's TRANSACTION makes it either everything is executed or nothing changes. The 'A' in the ACID characteristic of MySQL.

Related

In MySQL, can you insert multiple values to a row in a table

I am learning MySQL and I am very new to the concepts.
In one of my assignments, we are inserting values to our table.
In the table, there are several columns and the rows have multiple values in it.
outcome requested:
Does this create a constraint?
I feel like this is a trick question from my instructor.
Thank you in advance :)
My current draft:
Insert into sale (saleid, employeeid, personid, saledate)
Values (1,2,7,'2020-09-22'),
(2,3,1,'2020-09-22'),
(3,3,9,'2020-09-22');
Insert into saledetail (saleid, saledetailid, inventoryid, quantity)
Values (1,1,23456,3),
(1,1,23457,1),
(1,1,23460,2),
(2,2,23461,2),
(3,3,23462,1),
(3,3,23461,0.5),
(3,3,23457,1);
Correct, in you database, you should use two tables linked "one-to-many", where the second one contains all necessary "multiple values", one per row, and unique ID of a row in the first table.
Also, to ensure data consistency, you may want to use foreign key constraints: https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html

MySQL cascading tables

(My website is built using PHP and MySQL.)
My DB structure for users is mainly composed of 2 tables: "doctors" and "clients".
However, in order to integrate a chat system, I need to create a third table, namely 'chat_users', which combines both doctors and clients: fields of 'chat_users' table are
userid (unique integer),
username,
type (0:client, 1:doctor),
refid (id of the user in the associated clients or doctors table)
But I do not want to insert/delete/update this table manually each time a client or doctor is inserted/updated/deleted. I heard about cascading table some time ago...
What would be the best way performance-wise to do so? How can I achieve it?
I'm not sure you'll consider this an "answer", but may I comment on your database architecture?
You will be much happier in the long run having the following tables:
user_account: (ua_id, ua_email, ua_username, ua_password, etc.)
doctor: (d_id, ua_id, etc.)
customer: (c_id, ua_id, etc.)
In other words, have your relation going the other way. Then if you would like to be able to delete a doctor or customer by simply deleting the user_account, you can add the following relational constraint:
ALTER TABLE `doctor`
ADD CONSTRAINT `doctor_fk_user_account` FOREIGN KEY (`ua_id`) REFERENCES `user_account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `customer`
ADD CONSTRAINT `customer_fk_user_account` FOREIGN KEY (`ua_id`) REFERENCES `user_account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
What you need is an AFTER INSERT Trigger. This would allow you to create new users. In case if you want it to be updated on update and deleted on delete of the original record then you need those triggers as well.
CREATE TRIGGER `chat_users_insert` AFTER INSERT ON `doctors`
FOR EACH ROW BEGIN
INSERT INTO `chat_users` SET user_id= NEW.id;
END;
The above would insert a record and set the value of id. http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html can give you exact syntax. Let me know if you need any specific clarifications.
I know, this is not exactly an answer to your question but what about using an old fashioned view instead? This would save you from storing redundant data altogether.
CREATE VIEW chat_users AS
SELECT drid uid, drid userid, drname username, 0 FROM doctors
UNION ALL
SELECT clid+100000, clid, clname, 1 FROM clients
This view will have unique uids only if you don't have more than 100000 doctors in your table (otherwise choose a higher offset). The advantage of this approach would be that there is no dependent table data to maintain.
"I do not want to insert/delete/update this table manually each time a client or doctor is inserted/updated/deleted."
Why are you fretting about this? Just do it. You have application requirements that mandate it, so unless you can figure out how to unify your client and doctor tables, you will need a third that relates to your chat function.
The difficulty of adding this in an application framework is almost zero, it's just the case of creating an additional record when a client or doctor is created, and removing it when their respective record is deleted.
The other answers here propose using views or triggers to obscure what's really happening. This is generally a bad idea, it means your application isn't in charge of its own data, basically handing over control of certain application logic functions to the database itself.
The best solution is often the most obvious, as that leads to fewer surprises in the future.

mysql create table based on columns from another table and auto updated

I could have the wording 'wrong' here (new to mysql) but i hope i've explained what I'm trying to do well.
i have a table called submissions with 4 fields submitId, studentName, submitDate, status
status refers to whether they got admitted or not.
submitId is auto incremented
Now i wanted to create another table based on that, but only if the status is true, this new table would have the submitId, studentName, submitDate, plus additional fields.
this table would have a new auto increment studentId
how would i do that so it automatically updates any new entry to the first table on the second table, but not overwrite the additional content of table 2.
i thought of using a view, but u can't add new columns on the view, right?
do i have the logic wrong here or what are the options, could someone please point me in the right direction, thanks
You want to use a trigger. See:
http://dev.mysql.com/doc/refman/5.6/en/triggers.html
You can create the trigger so that when a row is inserted into submissions with status=true, it inserts a row into your new student table. It would look something like this:
delimiter //
CREATE TRIGGER sub_ins_check AFTER INSERT ON submissions
FOR EACH ROW
BEGIN
IF NEW.status = 1 THEN
INSERT INTO your_new_table (student_name, submit_date, submit_id) VALUES (NEW.student_name, NEW.submit_date, NEW.submit_id);
END IF;
END;//
delimiter ;
Then create another trigger so that when a row is updated in submissions, it updates the row with the same submit_id in your new table, like this:
delimiter //
CREATE TRIGGER sub_ins_check AFTER UPDATE ON submissions
FOR EACH ROW
BEGIN
IF NEW.status = 1 THEN
UPDATE your_new_table SET student_name = NEW.student_name, submit_date = NEW.submit_date, (etc..)) WHERE submit_id = NEW.submit_id;
END IF;
END;//
delimiter ;
I think your data model is wrong. Remember that student my have several submissions and there may be number of students with the same name. You must distinguish them.
Is there any reason you want to duplicate student data in both tables?
If you're new to SQL, read about table normalization first.
In you Student table you should store students data and in Submission table - guess what :)
The first thing you need to do is step back and consider the problem from the perspective of logical entities.
You've identified two entities that I can see - student and submission. "Student" is an obvious entity which you may choose NOT to store in your database, but it may be better that you do. "Submission" is a more obvious one, but what is not so obvious is what a "submission" actually is. Let's assume it is some sort of transaction.
You've mentioned a "second table" without a clear indication of its role in the solution. The best I could infer is that it is meant to be some sort of historical trail on activity against a submission. If true, then I could envision a physical schema sketched out as follows:
Student table. One row per student; contains information about a student (name, id, etc.). Primary key would probably be an auto-incremented number.
Submission table. One row per submission; includes a foreign key to the student table (referencing the primary key); has its own primary key, also an auto-incremented integer. Also has triggers defined for INSERT and UPDATE. INSERT trigger causes INSERT into submission_log table; UPDATE trigger also causes INSERT into submission_log table.
Submission_log table. One row per event against the submission table. Includes all the fields of submission plus its own primary key (submission's primary key is a foreign key here), and includes an indicator field for whether it represents an insert or update on submission.
The purpose of the above is not to supply a solution, or even the framework of a solution, but rather to get you to think in terms of the logical entities you want to model in your solution, and their relationships to each other. When you have a clear picture of the logical model, it will be much easier to determine what tables are required, what their roles are, and how they will be used and how they will relate to each other.

Database design: auto-increment key & update inconsistencies

Two tables share a unique identifier 'id'. Both tables are meant to be joined by using 'id'.
Defining 'id' as an auto incrementing primary key in both tables may risk update inconsistencies.
Is there some general pattern to avoid such a situation or do I have to deal with updating table1 first and table2 by utilizing the last inserted id after (therefore not declaring id as auto inc in table2)?
First, if you use InnoDB table engine in MySQL you could use both transactions and foreign keys for data consistency.
Second, after the insert in the first table, you could get the last insert id (depending on the way you access the db) and use it as foreign key.
Eg
Table 1: Users: user_id, username
Table 2: User_Profiles: user_id, name, phone
In User_Profiles you don't need to define user_id as auto increment, but first insert a record in Users table and use the user_id for the User_Profiles record. If you do this in transaction, the Users record won't be seen outside of the transaction connection until it's completed, this way you guarantee that even if something bad happens after you insert the user, but before you have inserted the profile - there won't be messed up data.
You could also define that the user_id column in User_Profiles table is foreign key of Users table thus if someone deletes a record from the Users table, the database would automatically delete the one in User_Profiles. There are many other options - read more about that.
There is no problem with same column name 'id' in any number of tables.
Several persistence layer frameworks do it same way.
Just use aliases in your SQL to distinct your tables accordingly.
do I have to deal with updating table1 first and table2 by utilizing the last inserted id after (therefore not declaring id as auto inc in table2)?
Yes. And make id a foreign key so it can only exist in table2 if it already exists in table1.
Yes you do, and remember to wrap the operation in a transaction.

mysql inserting with foreign key

i do have a form field which includes values which will be put in different tables in mysql.
they are all connected with foreign keys.
how do i put these values to different tables.
pseudo tables:
users_table:
userId|userlogin
user_info:
info_id|userId|name|surname
user_contact:
contact_id|userId|phone|email
form includes:
userlogin
name
surname
phone
email
in my research, i found out that i can use mysql_insert_id to link the FKs, but i wonder if that can cause problems if there is high load in the website (diff. requests sent at the same time).
i also found out that i can set triggers to create new fk values:
CREATE TRIGGER ins_kimlik AFTER INSERT ON hastalar
for each row
insert into hasta_kimlik set idhasta = new.idhasta
but i don't know how to add data to them. i can use
UPDATE table SET (name, surname) VALUES ('John', 'Brown') WHERE info_id = LAST_INSERT_ID();
but it doesn't feel the native way.
what is the best practise?
i found out that i can use mysql_insert_id to link the FKs, but i wonder if that can cause
problems if there is high load in the website (diff. requests sent at the same time).
mysql_insert_id returns the last auto-increment value generated by the database connection currently in use.
It doesn't matter what other processes do on other connections. It is safe. You'll get the right value.
but it doesn't feel the native way.
nope. The right way is :
INSERT user
get id
INSERT user_info
If the tables are connected by foreign keys shouldn't you just start with the basic table (users_table here) and then add in either user_info table and then in user_contact table, or the other way around. As long as you have filled in the table that has the primary key of the fk's in the other tables, then you can add easily.
INSERT SQL command:
INSERT INTO table_name (column1, column2, column3,...) VALUES (value1,
value2, value3,...)
Is that what you were asking?