简体   繁体   中英

mysql divide a table into 2 with different column names

I have a mysql table which I need to split into two. Currently the table contains info about two loosely related entities. For example the entities can be Employee of a firm and the firm's laptop he is tagged to. The following table explains my example. I have a table employee which has the following columns

employee_id,employee_name,employee_detail,join_date,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make.

I need to split this table into 2 as shown below. employee table without the laptop columns

employee_id,employee_name,employee_detail,join_date.

A new laptop table with employee_id as the key.

employee_id,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make

The below statements are true for the current database design

  • The employee table is heavily used by the back end code. The back end code is written in java and php.
  • employee table cannot be renamed.Implies I do not want to create 2 new tables.I want to retain the employee table, but remove all the laptop info from it.
  • New rows are added/existing rows are updated on a daily basis.

My question is

  1. Is there a design approach which I can follow for a smooth transition from the current design of a single table to the newly suggested design?
  2. Are there any best practices to follow to ensure a smooth transition.
  3. Could you suggest/re-direct me the steps to complete this task.
  1. Backup your existing database:

     mysqldump my_db > backup.sql 
  2. Create a new, empty table laptop (I'm not defining indexes or foreign key constraints in my example below, but you should do whatever is appropriate to your data structure):

     CREATE TABLE laptop SELECT employee_id, laptop_id, laptop_type, laptop_tagged_date, laptop_details, laptop_make FROM employee WHERE FALSE; 
  3. Define triggers on the original table to forward each type of write operation (insert/update/delete) to the new table:

     CREATE TRIGGER employee_insert AFTER INSERT ON employee FOR EACH ROW INSERT INTO laptop VALUES ( NEW.employee_id, NEW.laptop_id, NEW.laptop_type, NEW.laptop_tagged_date, NEW.laptop_details, NEW.laptop_make ); CREATE TRIGGER employee_update AFTER UPDATE ON employee FOR EACH ROW UPDATE laptop SET employee_id = NEW.employee_id, laptop_id = NEW.laptop_id, laptop_type = NEW.laptop_type, laptop_tagged_date = NEW.laptop_tagged_date, laptop_details = NEW.laptop_details, laptop_make = NEW.laptop_make WHERE employee_id <=> OLD.employee_id, laptop_id <=> OLD.laptop_id, laptop_type <=> OLD.laptop_type, laptop_tagged_date <=> OLD.laptop_tagged_date, laptop_details <=> OLD.laptop_details, laptop_make <=> OLD.laptop_make; CREATE TRIGGER employee_delete AFTER DELETE ON employee FOR EACH ROW DELETE FROM laptop WHERE employee_id <=> OLD.employee_id, laptop_id <=> OLD.laptop_id, laptop_type <=> OLD.laptop_type, laptop_tagged_date <=> OLD.laptop_tagged_date, laptop_details <=> OLD.laptop_details, laptop_make <=> OLD.laptop_make; 
  4. Empty the new table (of anything the trigger has since inserted) and then, within the same transaction , use INSERT ... SELECT to copy into it all incumbent data from the original table:

     START TRANSACTION; DELETE FROM laptop; INSERT INTO laptop SELECT employee_id, laptop_id, laptop_type, laptop_tagged_date, laptop_details, laptop_make FROM employee; COMMIT; 
  5. Thoroughly search your codebase (including database-stored programs) for all operations that access the laptop columns in the original table. Note whether each operation:

    • only reads from those columns;

    • only writes to those columns; or

    • both reads from and writes to those columns (eg UPDATE employee SET laptop_tagged_date = laptop_tagged_date + INTERVAL 1 WEEK WHERE ... ).

  6. Modify read operations to use the new table, splitting operations that both read and write into separate steps (eg UPDATE employee JOIN laptop ON ... SET employee.laptop_tagged_date = laptop.laptop_tagged_date + INTERVAL 1 WEEK WHERE ... ).

    This change does not need to be effected atomically, as the original and new tables will be kept in sync by the triggers: some parts of your application can therefore read from the new table whilst others continue using the original table.

    Do not proceed to the next step until you are satisfied that this step has been completed , as the next step will result in the tables becoming desynchronised. You could even use MySQL user permissions to prevent writing to the new table (except by the triggers) until you are satisfied that this step is complete.

  7. Modify write operations to use the new table.

    This change does not need to be effected atomically, as any writes to the original table will be forwarded to the new one by the triggers: some parts of your application can therefore write to the new table whilst others continue writing to the original table.

  8. Drop the columns from the original table:

     ALTER TABLE employee DROP COLUMN laptop_id, DROP COLUMN laptop_type, DROP COLUMN laptop_tagged_date, DROP COLUMN laptop_details, DROP COLUMN laptop_make; 

if you want to have 2 physical different tables you can adapt Sebastien M. answer as such :

create a laptop table with corresponding data to externalize them

CREATE TABLE laptop AS
SELECT DISTINCT employee_id,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make
FROM employee
WHERE ...

provide a employee_laptop view to imitate the behaviour of employee and get backward compatibility

create view employee_laptop as 
select employee_id, e.employee_name,e.employee_detail,e.join_date,
       l.laptop_id,l.laptop_type,l.laptop_tagged_date,l.laptop_details,l.laptop_make
from employee e join laptop l using(employee_id);

then you have all the latitude to drop the unnecessary columns from the employee table

I can suggest you a possible way , when you are creating laptop table use the following query type :-

create table laptop select employee_id,laptop_id,laptop_type,
laptop_tagged_date,laptop_details,laptop_make from
employee;

After creating the laptop table in this above process, you can remove the specified columns from employee table for getting your new employee table with relevant fields.

Delete column from employee table.

alter table employee
drop column laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make;

Now the new employee table has following fields :

employee_id,employee_name,employee_detail,join_date

Now the laptop table has following fields :

mployee_id,laptop_id,laptop_type,
    laptop_tagged_date,laptop_details,laptop_make

Hope it will help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM