› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
flowyi
V2EX  ›  MySQL

MySQL 数据库表合并问题

  •  
  •   flowyi · May 29, 2014 · 6679 views
    This topic created in 4518 days ago, the information mentioned may be changed or developed.
    我们之前的某块业务是表是分开的,
    比如一个业务用两个表存数据,T_a 和 T_b。
    现在需要把他们合并,他们的表结构是
    T_a:
    c1 c2
    1 1
    2 2
    3 3

    T_b:
    c1 c3
    1 11
    2 22

    合并之后的表:
    T_c:
    c1 c2 c3
    1 1 0
    2 2 0
    3 3 0
    1 0 11
    2 0 22
    即理论上简单的从a和b表select出来插入c就可以了,原来没有的字段留空(一般是0)
    但是问题是不能停机太久,我们的数据量比较大(1kw量级),上面的方法我在测试环境发现
    插入的时候耗时太久。请问各位有什么更好的方法或建议吗?
    Supplement 1  ·  May 30, 2014
    不好意思可能没表达清楚。其实系统是可以停止服务的,重大更新,没办法~ 只是停机的时间尽量短。几个小时可以接受吧,找个夜黑风高的深夜……
    8 replies  •  2014-05-30 17:06:00 +08:00
    Mac
        1
    Mac  
       May 29, 2014
    INSERT INTO T_a (c1,c2,c3) SELECT c1,c2,c3 FROM T_b

    哪个数据多就做主表,数据少的做来源,这样起码你省一半时间了吧。KW级的数据在你的环境里要INSERT多久?
    Mac
        2
    Mac  
       May 29, 2014   ❤️ 1
    先在T_a中增加一列c3,默认值0
    然后再T_b中加入一列c2,默认值0
    自己调整好字段顺序,使得两个表结构是一样的
    INSERT INTO T_a (c1,c2,c3) SELECT c1,c2,c3 FROM T_b
    然后更改T_a表名为T_c

    哪个数据多就做主表,数据少的做来源,这样起码你省一半时间了吧。
    pubby
        3
    pubby  
       May 29, 2014
    @Mac 旧表新增一列其实也是表复制,kw级的也得很久
    pubby
        4
    pubby  
       May 29, 2014   ❤️ 1
    一、如果T_a T_b可以有较长时间停止数据更新
    1. 修改业务代码,暂时停掉会导致T_a T_b更新的功能
    2. 构建T_c
    3. 直接切换到新业务代码使用T_c

    二、如果T_a/T_b不能长时间停止写入
    1. 写个触发器,记录T_a/T_b上的更新
    2. 构建T_c
    3. 停掉业务,把触发器收集到的更新记录还原到T_c上(量应该不会太大吧)
    4. 切换到新业务代码使用T_c


    以上只是随便想象,还需专业DBA来分析下
    xifangczy
        5
    xifangczy  
       May 29, 2014   ❤️ 1
    我有个想法,如果你测试环境和业务环境交换数据很快的话。
    业务环境里开始做记录然后测试环境开始合并,合并完成后停机,把记录的数据更新到刚刚合并好的数据库上,测试完成上线。
    czheo
        6
    czheo  
       May 29, 2014   ❤️ 1
    start a slave mysql server on a remote machine(if no another machine is available, just start another mysql on the local machine as a slave)
    1. slave> create slave.T_a both with c1, c2, c3
    2. slave> replicate master.T_a -> slave.T_a
    3. client> get offline for a short while. (to avoid any writing to master.T_a after you've done step 4)
    4. slave> rename slave.T_a -> slave.T_b
    5. client> redirect operations of master.T_a -> slave.T_b and get online
    6. slave> replicate master.T_b -> slave.T_b
    7. client> redirect operations of master.T_b -> slave.T_b

    slave.T_b will be what you referred as T_c
    czheo
        7
    czheo  
       May 29, 2014
    1. slave> create slave.T_a with column c1, c2, c3
    flowyi
        8
    flowyi  
    OP
       May 30, 2014
    @Mac
    @pubby
    @xifangczy
    @czheo

    感谢各位的idea,都很有想法。
    我目前的想法是分别把T_a和T_b用 "mysqldump --tab" 整个表dump出来,然后用
    "mysqlimport --columns=column_list"的方式导入T_c,测试比insert快了很多。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2936 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 15:06 · PVG 23:06 · LAX 08:06 · JFK 11:06
    ♥ Do have faith in what you're doing.