【问题标题】:Switching from MySQL to PostgreSQL - tips, tricks and gotchas?从 MySQL 切换到 PostgreSQL - 提示、技巧和陷阱?
【发布时间】:2010-10-20 19:16:14
【问题描述】:

我正在考虑从 MySQL 切换到 PostgreSQL。

您在使用 PostgreSQL 时有哪些提示、技巧和注意事项?

MySQLer 应该注意什么?

另请参阅:How different is PostgreSQL to MySQL?
另见:Migrate from MySQL to PostgreSQL

注意 - 我不认为这是重复的。特别是答案的类型非常不同,这里的响应有更多的实现细节,这正是我正在寻找的

【问题讨论】:

  • 请注意:这实际上与有关 Oracle 和 Sun 的新闻无关。我有一个 Rails 应用程序,它需要多个数据库并正在考虑使用 PostgreSQL 模式。

标签: mysql postgresql migration load-data-infile


【解决方案1】:

除了移动数据库结构,您无法避免手动调整...

传输数据最可靠的方法(逐表,只要结构相同):

mysql --default-character-set=utf8 -e "SELECT * FROM mytable" > mytable.txt

psql
\copy mytable from '/path/to/mytable.txt' WITH NULL AS 'NULL';

最近一直在尝试其他所有方法(例如带有大量选项的 mysqldump + sed 等),但没有什么比这更好。

当结构发生变化时,这种方法还具有一定的灵活性 - 只需编写适当的 SELECT。

【讨论】:

    【解决方案2】:

    我发现这个脚本将连接到您的 MySQL 数据库和您的 PostgreSQL 数据库并传输内容。它对我来说就像一种魅力。

    https://github.com/philipsoutham/py-mysql2pgsql

    安装者

    $ pip install py-mysql2pgsql
    

    运行

    $ py-mysql2pgsql
    

    在任何文件夹中,它将为您创建一个模板设置文件 (mysql2pgsql.yml),您可以在其中编辑和输入数据库的详细信息。

    我必须安装 argparse 才能工作。

    $ pip install argparse
    

    当您的数据库详细信息填写完毕后,再次运行即可

    $ py-mysql2pgsql
    

    在与设置文件相同的文件夹中,然后,您就完成了。它没有在屏幕上打印任何内容,但之后我的数据库被完全复制了。

    【讨论】:

    • 我刚刚发现我无法在我的论坛(使用数据库的软件)中添加任何帖子或评论,但是通过将 postgresql 数据库导出到文件,删除并创建数据库来解决它,并导入文件。谁知道,我可能只是在我第一次导入它的 test-db 中为用户设置了错误的用户权限..
    【解决方案3】:

    我自己刚刚经历过,好吧,我仍然......

    • 区分大小写的文本
    • 缺少INSERT IGNOREREPLACE
    • 几乎所有地方都需要显式转换
    • 没有反引号
    • LOAD DATA INFILECOPY 很接近,但还不够接近)
    • autoincrement 更改为SERIAL
    • 虽然在 MySQL 中的格式不好,但在 Postgres 中,没有 ON 子句的 INNER JOIN 不会发生,请使用 CROSS JOIN
    • COUNT(*) 可能会很慢
    • 数据库是用字符集编码的,而不是表
    • 您可以拥有多个数据库,具有多个架构(MySQL 确实只有一个数据库和多个架构)
    • 分区不同
    • MySQL interval 与 Postgres interval(时间间隔)
    • 隐式列重命名,Postgres 需要AS
    • 不能在 Postgres 中同时更新多个表
    • Postgres 功能强大。所以没有CALL proc();;将proc() 重写为函数和SELECT proc();

    【讨论】:

    • @OMG Ponies:在现代 PG 版本中,您不必为自动 ID 显式使用序列。 serial 和 bigserial 类型隐藏了它的所有语义,但它仍然是一个序列及其所有功能。他们创建了一个自动命名的序列并将列的默认值设置为 nextval。
    • 我来自Oracle,所以我对序列有偏好。何时引入串行/大串行功能 - 8.x?
    • @OMG Ponies:手册上的内容可以追溯到 7.1。串行/大串行实际上只是一个“魔术”技巧。初始创建后,它显示为整数/大整数和序列。
    • 你是说 Count(*) 很慢,但是说 Count(id) 会工作得相当快?还是说 PostgreSQL 的 Count() 通常很慢?
    • @Mr_Chimp count() 在 Postgres 中很慢,因为由于 MVCC,它必须出去查看磁盘上的所有行。在 9.2 中,由于在某些情况下使用 index-only-scans 的能力,您可以加快速度,但事实是通常 count() 会比 MySQL 慢。然而,权衡是您可以获得读者和作者不会相互等待,这在某些工作负载上可能是一个巨大的优势。
    【解决方案4】:

    这将是一项艰巨的任务,因为您必须测试整个代码库 - 任何地方的每一个查询

    • 语法
    • 正确的行为(即返回相同的结果)
    • 性能 - 例如是否有任何性能下降/改进,你能处理它们吗?
    • 错误处理 - 它们在错误条件下的行为不同,可能您的代码依赖于特定的错误代码

    在操作上您需要查看:

    • 备份/恢复
    • 磁盘空间利用率
    • 内存利用率
    • 一次性数据迁移 - 可能是一项大/耗时的任务
    • 失败时的回滚计划
    • 监控 - 您如何监控 MySQL,这些方法是否可以调整
    • (如果相关)- 复制

    在考虑采取这样的举措之前,您肯定需要进行大量的性能测试。

    这些成本使得迁移到不同的数据库对于大多数重要的应用程序来说过于昂贵。仔细考虑一下这些好处非常与执行上述所有操作的巨额成本相比。

    如果您在一个非平凡的应用程序中花费不到三个月的时间,我会感到惊讶,在此期间您将无法继续常规开发。

    【讨论】:

    • 这是一个新项目,所以现阶段迁移没有成本。但这都是值得考虑的绝佳建议。
    【解决方案5】:

    在转换之前,通过使用以下命令启动服务器,将 MySQL 设置为 ANSI 严格:--transaction-isolation=SERIALIZABLE --sql-mode=ANSI

    确保您没有使用 MyIsam 表。

    MySQL 允许大量不应该的转换; pg 将需要演员表。

    您的存储过程、函数和触发器必须重新编写。 pg 为您提供了这些语言的选择,但您必须安装这些语言;它不像 MySQL 那样用户友好。

    pg 将只允许在一个选择列表中的列在 group by 或聚合;如果这样做,MySQL 将通过选择组中的第一个值来作弊。

    MySQL 增加了一堆扩展:不等于运算符可以是!=,就像在 C 中一样,它允许 '&&' 作为 'and'、'||' 的同义词对于“或”等。特别是,pg 使用“||”表示字符串连接。

    基本上,pg 是非常严格的 ANSI,而 MySQL 不是。我强烈建议在转换为 pg 之前让您的 MySQL 尽可能严格地遵守 ANSI,然后在运行应用程序时检查是否有任何警告。

    【讨论】:

      【解决方案6】:

      您可以尝试包含最常见问题的PostgreSQL gotchas。一般来说,PostgreSQL 文档也很不错,所以也请把它放在枕头底下。

      另外,Converting from MySQL to PostgreSQL 在 pgsql wiki 上。

      【讨论】:

        猜你喜欢
        • 2011-01-11
        • 1970-01-01
        • 2010-09-16
        • 2010-09-16
        • 1970-01-01
        • 1970-01-01
        • 2014-10-28
        • 2021-10-22
        相关资源
        最近更新 更多