[英]mysql divide a table into 2 with different column names
I have a mysql table which I need to split into two. 我有一个mysql表,需要将其拆分为两个。 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
表,其中有以下几列
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. 我需要将此表拆分为2,如下所示。 employee
table without the laptop columns 没有笔记本电脑列的employee
表
employee_id,employee_name,employee_detail,join_date.
A new laptop
table with employee_id as the key. 一个新的laptop
表,其中有employee_id作为键。
employee_id,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make
The below statements are true for the current database design 以下陈述适用于当前的数据库设计
employee
table is heavily used by the back end code. 后端表大量使用了employee
表。 The back end code is written in java and php. 后端代码是用Java和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. 不能重命名employee
表。示例,我不想创建2个新表。我想保留employee
表,但是要从中删除所有笔记本电脑信息。 My question is 我的问题是
Backup your existing database: 备份现有数据库:
mysqldump my_db > backup.sql
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): 创建一个新的空表laptop
(在下面的示例中,我没有定义索引或外键约束,但是您应该做适合于您的数据结构的任何事情):
CREATE TABLE laptop SELECT employee_id, laptop_id, laptop_type, laptop_tagged_date, laptop_details, laptop_make FROM employee WHERE FALSE;
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;
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: 清空新表(此后已插入触发器的所有数据),然后在同一事务中 ,使用INSERT ... SELECT
复制原始表中的所有现有数据:
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;
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 ...
). 都从这些列中读取和写入(例如UPDATE employee SET laptop_tagged_date = laptop_tagged_date + INTERVAL 1 WEEK WHERE ...
)。
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 ...
). 修改读取操作以使用新表,将读取和写入的操作分成单独的步骤(例如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. 您甚至可以使用MySQL用户权限来阻止写入新表(触发器除外),直到您满意此步骤已完成。
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. 无需原子地进行此更改,因为对触发器的任何原始表写入操作都将被触发器转发到新表:因此,应用程序的某些部分可以写入新表,而其他部分则可以继续写入原始表。
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 : 如果您想拥有2个物理上不同的表,则可以像这样修改Sebastien M.答案:
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 提供一个employee_laptop视图以模仿员工的行为并获得向后兼容性
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 那么您就可以自由地从employee表中删除不必要的列
I can suggest you a possible way , when you are creating laptop
table use the following query type :- 我可以建议您一种可能的方式,当您创建laptop
表时,请使用以下查询类型:-
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. 在上述过程中创建laptop
表后,您可以从employee
表中删除指定的列,以获取具有相关字段的新员工表。
Delete column from employee
table. 从employee
表中删除列。
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
表具有以下字段:
employee_id,employee_name,employee_detail,join_date
Now the laptop
table has following fields : 现在, laptop
表具有以下字段:
mployee_id,laptop_id,laptop_type,
laptop_tagged_date,laptop_details,laptop_make
Hope it will help you. 希望对您有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.