PostgreSQL数据库对比mysql快速复制空表的技巧实例

MySQL 有一个和优秀的语法 create table ... like , 可以快速复制一张表,创建其副本。 PostgreSQL 也有类似的语法,而且更加灵活,不过要注意些细节。

先来看看MySQL 语法: create table ... like
原始表T1,结构如下:

    +----------+------------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +----------+------------------+------+-----+---------+----------------+
    | id | int(10) unsigned | NO | PRI | NULL | auto_increment |
    | log_time | datetime(6) | YES | | NULL | |
    +

快速做一张副本:

    mysql> create table t2 like t1;
    Query OK, 0 rows affected (0.03 sec)

这时会有一张相同的副本表快速产生:

    +----------+------------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +----------+------------------+------+-----+---------+----------------+
    | id | int(10) unsigned | NO | PRI | NULL | auto_increment |
    | log_time | datetime(6) | YES | | NULL | |
    +----------+------------------+------+-----+---------+----------------+

这时注意到,这里用到自增字段作为主键,不过MySQL 这类语法不会沿用原始表的自增位置,还是从头开始。不过这点说起来难免搞笑,因为MySQL没有单独的序列。

    mysql> insert into t2 (log_time) select now();
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0

    mysql> select * from t2;
    +----+----------------------------+
    | id | log_time |
    +----+----------------------------+
    | 1 | 2014-11-27 13:44:12.000000 |
    +----+----------------------------+
    1 row in set (0.00 sec)

现在来看下PostgreSQL:
原始表结构如下, 包含了一个序列作为主键。

    Table "ytt_sql.t1"
      Column | Type | Modifiers
    ----------+-----------------------------+-------------------------------------------------
     id | integer | not null default nextval('t1_id_seq'::regclass)
     log_time | timestamp without time zone |
    Indexes:
        "t1_pkey" PRIMARY KEY, btree (id)

    Table "ytt_sql.t1"
      Column | Type | Modifiers
    ----------+-----------------------------+-------------------------------------------------
     id | integer | not null default nextval('t1_id_seq'::regclass)
     log_time | timestamp without time zone |
    Indexes:
        "t1_pkey" PRIMARY KEY, btree (id)

用类似的语法create table ... like 来创建副本:

    t_girl=# create table t2 (like t1 including all);
    CREATE TABLE
    Time: 50.035 ms

副本的表结构如下,不过可能发现了一个问题,连同原始表的序列也一起弄过来了,这个太不安全了。

    Table "ytt_sql.t2"
      Column | Type | Modifiers
    ----------+-----------------------------+-------------------------------------------------
     id | integer | not null default nextval('t1_id_seq'::regclass)
     log_time | timestamp without time zone |
    Indexes:
        "t2_pkey" PRIMARY KEY, btree (id)

而此时查看到这个序列的指针已经是120了,那么副本表的记录不是要从120开始?而且副本表的插入或者其他写入操作都会影响原始表!

    t_girl=# select currval('t1_id_seq');
     currval
    ---------
         120
    (1 row)

    Time: 3.771 ms

所以这时重新创建一个新的序列给副本表专用:

    t_girl=# create sequence t2_id_seq;
    CREATE SEQUENCE
    Time: 12.744 ms

更新这列的默认值。

    t_girl=# alter table t2 alter id set default nextval('t2_id_seq');
    ALTER TABLE
    Time: 5.002 ms

这时候插入些记录看看:

    t_girl=# insert into t2 (log_time) values ....;
    INSERT 0 10
    Time: 10.331 ms

这时记录从1开始了:

    t_girl=# select * from t2;
     id | log_time
    ----+----------------------------
      1 | 2014-03-09 06:49:14.393962
      2 | 2005-12-30 05:49:14.393962
      3 | 2014-05-17 20:49:14.393962
      4 | 2004-06-15 22:49:14.393962
      5 | 2010-06-19 03:49:14.393962
    ...
     10 | 2009-09-07 23:49:14.393962
    (10 rows)

    Time: 4.958 ms

不过我这里LIKE了所有选项,也可以不不包括默认值,这样,序列本身就不会复制进来了。

    t_girl=# create table t2 (like t1 including all excluding defaults);
    CREATE TABLE
    Time: 40.292 ms

                     Table "ytt_sql.t2"
      Column | Type | Modifiers
    ----------+-----------------------------+-----------
     id | integer | not null
     log_time | timestamp without time zone |
    Indexes:
        "t2_pkey" PRIMARY KEY, btree (id)

这里也可以不用LIKE 选项,直接用类似CREATE TABLE AS ...语法,如下:
创建没有记录的空表,但是这里只包含了表结构以及字段相关。

    t_girl=# create table t2 as table t1 with no data;
    SELECT 0
    Time: 15.562 ms
    或者
    t_girl=# create table t2 as select * from t1 where false;
    SELECT 0
    Time: 14.181 ms

我们手动给添加主键以及默认值。

    t_girl=# alter table t2 add constraint pk_t2_id primary key (id), alter id set default nextval('t2_id_seq');
    ALTER TABLE
    Time: 41.105 ms

结构跟原来一样了。

    Table "ytt_sql.t2"
      Column | Type | Modifiers
    ----------+-----------------------------+-------------------------------------------------
     id | integer | not null default nextval('t2_id_seq'::regclass)
     log_time | timestamp without time zone |
    Indexes:
        "pk_t2_id" PRIMARY KEY, btree (id)

时间: 2024-09-20 06:20:35

PostgreSQL数据库对比mysql快速复制空表的技巧实例的相关文章

MySQL快速复制数据表与数据库的方法

以下范例都是把 old_table 复制到 new_table. 先讲讲结论, 最推荐的作法是下述两行:  代码如下 复制代码 ■CREATE TABLE new_table LIKE old_table; ■INSERT new_table SELECT * FROM old_table; 以下来讲讲几种作法 和 优缺点. MyISAM 的作法若比较暴力点的话, 可以用下述方式做:  代码如下 复制代码 1.CREATE TABLE new_table; 2./etc/init.d/mysql

MySQL快速复制数据库数据表的方法_Mysql

某些时候,例如为了搭建一个测试环境,或者克隆一个网站,需要复制一个已存在的mysql数据库.使用以下方法,可以非常简单地实现. 假设已经存在的数据库名字叫db1,想要复制一份,命名为newdb.步骤如下: 1. 首先创建新的数据库newdb #mysql -u root -ppassword mysql>CREATE DATABASE `newdb` DEFAULT CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI; 2. 使用mysqldump及mysql的

PostgreSQL数据库中没有主键的表增加主键

PostgreSQL数据库测试环境中有多张表没有添加主键约束,只有一个serial的自增字段.现在需要把那些没有主键的表都加上,serial类型的字段为id . 首先是怎么找到PostgreSQL数据库中哪些表没有主键?我们看下pg_class这个表,里面有个relhaspkey字段,如果为t说明有主键,f即没有主键.例如下面这个sql . SELECT n.nspname AS "Schema",c.relname AS "Table Name",c.relhas

MySQL中两种快速创建空表的方式的区别

在MySQL中有两种方法 1.create table t_name select ... 2.create table t_name like ... 第一种会取消掉原来表的有些定义,且引擎是系统默认引擎. 手册上是这么讲的:Some conversion of data types might occur. For example, the AUTO_INCREMENT attribute is not preserved, and VARchar columns can become ch

MySQL中复制数据表中的数据到新表中的操作教程_Mysql

MySQL是不支持SELECT - INTO语法的,使用INSERT INTO - SELECT替代相同用法,下面我们我们这里简答分一下新表存在和不存在两种情况,具体使用不同的语句.1.新表不存在复制表结构即数据到新表 create table new_table select * from old_talbe; 这种方法会将old_table中所有的内容都拷贝过来,用这种方法需要注意,new_table中没有了old_table中的primary key,Extra,auto_incremen

ACCESS数据库向MySQL快速迁移小程序(一)

access|mysql|程序|数据|数据库 近日,本人为了将为公司开发的一个信息管理系统从以前试运行的开发机器上(Windows NT + IIS4.0 + Access)迁移至一台真正的Linux服务器上(Apache1.3.12 + PHP 4.03 + MySQL 3.23.26),其中数据库中的几十个表的内容迁移,开始让我小费了一些周折,从网上也下载了一些MySqL的客户软件或是数据库管理软件,写得较好的软件均有数据迁移功能,但其迁移方式不外乎两种,一种是采用文件引入方式,此种方式在处

ACCESS数据库向MySQL快速迁移小程序

近日,本人为了将为公司开发的一个信息管理系统从以前试运行的开发机器上(Windows NT IIS4.0 Access)迁移至一台真正的Linux服务器上(Apache1.3.12 PHP 4.03 MySQL 3.23.26),其中数据库中的几十个表的内容迁移,开始让我小费了一些周折,从网上也下载了一些MySqL的客户软件或是数据库管理软件,写得较好的软件均有数据迁移功能,但其迁移方式不外乎两种,一种是采用文件引入方式,此种方式在处理数据库中有和分隔符相同的字符时,会产生错误,尤其是在处理AC

ACCESS数据库向MySQL快速迁移小程序(二)

access|mysql|程序|数据|数据库 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 以下为 import.php 源程序 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <html> <head> <style type=text/css> body,td,li,div,p,pre,a,b,h1,h2,h3,h4 {font-family:verdana;font-size:9pt;lin

CorelDraw中快速复制的方法与技巧

一.快速拷贝色彩和属性 在CorelDraw软件中,给其群组中的单个对象着色的最快捷的方法是把屏幕调色板上的颜色直接拖拉到对象上.同样地道理,拷贝属性到群组中的单个对象的捷径是在用户拖拉对象时按住鼠标右键,而此对象的属性正是用户想要拷到目标对象中去的.当用户释放按钮时,程序会弹出一个右键显示菜单,在菜单中用户可以选择自己想要拷贝的属性命令. 二.让渐变效果更平滑 渐变效果是图象制作过程中常用的一种效果,如何把这种效果的渐变层次处理得更平滑.更自然一点,就变得非常重要了.在CorelDraw中,获