mysql将表分成2个不同的列名

时间:2012-09-13 12:27:04

标签: mysql

我有一个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.

以employee_id为键的新laptop表。

employee_id,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make

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

  • 后端代码大量使用employee表。背部 结束代码用java和php编写。
  • employee表无法重命名.Implies我不想创建2 新表。我想保留employee表,但删除所有表 来自它的笔记本电脑信息。
  • 添加新行/每天更新现有行。

我的问题是

  1. 是否有一种设计方法可以让我顺利进行 从单个表的当前设计过渡到新表 建议设计?
  2. 是否有任何最佳做法可以确保顺利进行 过渡。
  3. 您能否建议/重新指导我完成此任务的步骤。

3 个答案:

答案 0 :(得分:2)

  1. Backup您现有的数据库:

    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. 在原始表上定义triggers以将每种类型的写操作(插入/更新/删除)转发到新表:

    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;
    

答案 1 :(得分:1)

如果你想拥有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表中删除不必要的列

答案 2 :(得分:1)

我建议你一种可能的方法,当你创建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

希望它会对你有所帮助。