繁体   English   中英

mysql将表分为两个具有不同列名的表

[英]mysql divide a table into 2 with different column names

我有一个mysql表,需要将其拆分为两个。 当前,该表包含有关两个松散相关实体的信息。 例如,实体可以是公司的雇员,而公司的便携式计算机可以被标记为该公司的笔记本电脑。 下表说明了我的示例。 我有一个employee表,其中有以下几列

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

我需要将此表拆分为2,如下所示。 没有笔记本电脑列的employee

employee_id,employee_name,employee_detail,join_date.

一个新的laptop表,其中有employee_id作为键。

employee_id,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make

以下陈述适用于当前的数据库设计

  • 后端表大量使用了employee表。 后端代码是用Java和php编写的。
  • 不能重命名employee表。示例,我不想创建2个新表。我想保留employee表,但是要从中删除所有笔记本电脑信息。
  • 添加新行/每天更新现有行。

我的问题是

  1. 我是否可以遵循一种设计方法,以便从单个表的当前设计顺利过渡到新建议的设计?
  2. 有什么最佳实践可遵循,以确保平稳过渡。
  3. 您能否建议/重定向我完成此任务的步骤。
  1. 备份现有数据库:

     mysqldump my_db > backup.sql 
  2. 创建一个新的laptop (在下面的示例中,我没有定义索引或外键约束,但是您应该做适合于您的数据结构的任何事情):

     CREATE TABLE laptop SELECT employee_id, laptop_id, laptop_type, laptop_tagged_date, laptop_details, laptop_make FROM employee WHERE FALSE; 
  3. 在原始表上定义触发器 ,以将每种类型的写入操作(插入/更新/删除)转发到新表:

     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. 清空新表(此后已插入触发器的所有数据),然后在同一事务中 ,使用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; 
  5. 彻底搜索您的代码库(包括数据库存储的程序)以查找访问原始表中便携式计算机列的所有操作。 注意是否每个操作:

    • 仅从这些列读取;

    • 仅写入这些列; 要么

    • 都从这些列中读取和写入(例如UPDATE employee SET laptop_tagged_date = laptop_tagged_date + INTERVAL 1 WEEK WHERE ... )。

  6. 修改读取操作以使用新表,将读取和写入的操作分成单独的步骤(例如UPDATE employee JOIN laptop ON ... SET employee.laptop_tagged_date = laptop.laptop_tagged_date + INTERVAL 1 WEEK WHERE ... )。

    无需原子地进行此更改,因为触发器将使原始表和新表保持同步:因此,应用程序的某些部分可以从新表中读取,而其他部分则可以继续使用原始表。

    在您确定此步骤已完成之前请勿继续进行下一步 ,因为下一步将导致表不同步。 您甚至可以使用MySQL用户权限来阻止写入新表(触发器除外),直到您满意此步骤已完成。

  7. 修改写操作以使用新表。

    无需原子地进行此更改,因为对触发器的任何原始表写入操作都将被触发器转发到新表:因此,应用程序的某些部分可以写入新表,而其他部分则可以继续写入原始表。

  8. 删除原始表中的列:

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

如果您想拥有2个物理上不同的表,则可以像这样修改Sebastien M.答案:

创建带有相应数据的笔记本电脑表以将其外部化

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

提供一个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);

那么您就可以自由地从employee表中删除不必要的列

我可以建议您一种可能的方式,当您创建laptop表时,请使用以下查询类型:-

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

在上述过程中创建laptop表后,您可以从employee表中删除指定的列,以获取具有相关字段的新员工表。

employee表中删除列。

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

现在,新employee表具有以下字段:

employee_id,employee_name,employee_detail,join_date

现在, laptop表具有以下字段:

mployee_id,laptop_id,laptop_type,
    laptop_tagged_date,laptop_details,laptop_make

希望对您有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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