我有一个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
表,但删除所有表
来自它的笔记本电脑信息。我的问题是
答案 0 :(得分:2)
Backup您现有的数据库:
mysqldump my_db > backup.sql
创建一个新的空表laptop
(我在下面的示例中没有定义索引或外键约束,但您应该做适合您的数据的任何事情结构):
CREATE TABLE laptop
SELECT employee_id,
laptop_id,
laptop_type,
laptop_tagged_date,
laptop_details,
laptop_make
FROM employee
WHERE FALSE;
在原始表上定义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;
清空新表(已插入触发器的任何内容),然后在同一事务中使用 ,使用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;
彻底搜索代码库(包括数据库存储程序),以查找访问原始表中笔记本电脑列的所有操作。注意每个操作是否都是:
仅从这些列中读取;
仅写入这些列;或
读取和写入这些列(例如UPDATE employee SET laptop_tagged_date = 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 ...
)。
此更改不需要以原子方式实现,因为原始表和新表将通过触发器保持同步:因此,应用程序的某些部分可以从新表中读取,而其他部分则继续使用原始表。
在您对此步骤的完成感到满意之前,请不要继续执行下一步,因为下一步将导致表变得不同步。您甚至可以使用MySQL用户权限来阻止写入新表(触发器除外),直到您对此步骤完成感到满意为止。
修改写操作以使用新表。
此更改不需要以原子方式实现,因为对原始表的任何写入都将通过触发器转发到新表:因此,应用程序的某些部分可以写入新表,而其他部分继续写入原始表表
从原始表中删除列:
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
希望它会对你有所帮助。