Миграция MySQL на PostgreSQL — какие функции, не видимые в коде SQL, будут важны?

Мы переносим MySQL на PostgreSQL. Я могу легко проверить схему и операторы SQL, используемые во всей (REALbasic) программе. Большая часть SQL состоит из построения строковых переменных.

Я уже знаю о необходимости заменить использование SELECT LAST_INSERT_ID() столбцом SERIAL с ограничением UNIQUE.

Какие, если они есть, различия между ними, которые не явно видны в операторах SQL, могут нас укусить? Я ищу (возможно, тонкие) предположения о поведении, такие как любые различия в автофиксации, необходимость добавления ограничений, которых нет в MySQL и т. д.

Я пытаюсь найти какие-нибудь подводные камни для пары достаточно умных и внимательных парней, которые не являются гуру ни в одной из баз данных.

Это одностороннее обязательство, поэтому, если есть серьезные преимущества, которые мы получим, добавив новые декларации, я был бы признателен, если бы они указали на них.

Примечание: мы не используем какую-либо форму параметризованных запросов, и да, я указал на проблемы с инъекционными атаками как на обязательный аудит кода.

Да, для любопытных, это решение было вызвано проблемами с GPL, не то чтобы мы не хотели платить за лицензии, но, к сожалению, единственным НАСТОЯЩИМ базовым драйвером для MySQL была GPL. В мае 2009 года Real Software выпустила новый драйвер сообщества, который находится под лицензией GPL и включает исходный код. Обещали в ближайшем будущем драйвер Enterprise без лицензии GPL.

Я готов поверить, что ответ может быть таким: под кроватью нет невидимых монстров, но решил спросить, чтобы быть уверенным.


person Andy Dent    schedule 13.01.2009    source источник


Ответы (7)


  • select count(*) from table;

    будет медленным, так как ему нужно прочитать всю таблицу. Нужны обходные пути, если вам нужно часто подсчитывать большие таблицы. Это необходимо для обеспечения управления многоверсионностью.

  • В последней версии (8.3) нет неявного приведения к тексту, что означает, например,

    select 234 like '2%';

    выдаст ошибку. Вам понадобится явное приведение, например:

    select 234::text like '2%';

  • Обновление — это удаление + вставка. Поскольку пространство, используемое удаленными строками, не освобождается сразу, если вы обновляете всю таблицу за одну транзакцию, вам потребуется удвоить пространство.

Postgresql — очень хорошая база данных, она вам очень понравится. У него есть несколько очень полезных функций, которых вам не хватает в других, даже коммерческих базах данных. Например, язык определения транзакционных данных или точки сохранения.

person Tometzky    schedule 04.02.2009
comment
спасибо, это была именно та поведенческая ошибка, о которой я беспокоился. - person Andy Dent; 06.02.2009


Когда я переходил с MySQL на PostgreSQL, мне действительно мешало несколько вещей:

1) Код, записывающий в базу данных MySQL, был сломан, и подача мусора в базу данных реальной базой данных, у которой были внешние ключи, предотвратила бы. Будьте готовы найти "сюрприз" мусорных данных, как только вы добавите ссылочную целостность.

2) Индексы MySQL для строк нечувствительны к регистру! Если у вас есть первичный ключ для чего-то вроде имени пользователя, «Coryking» и «CORYKING» совпадают в соответствии с MySQL. В PostgreSQL они разные. Я не знал об этом, пока не начали появляться люди, которые регистрировали повторяющиеся имена пользователей, которые уже должны были быть в базе данных.

3) MySQL любит автоматически добавлять бессмысленные значения по умолчанию к столбцам, которые вы указываете как «NOT NULL». Например, если вы укажете VARCHAR(255) NOT NULL, это превратит определение этого столбца в «VARCHAR(255) NOT NULL DEFAULT ''».

4) PostgreSQL любит большие запросы, MySQL — нет. Вы получите массу удовольствия после того, как миграция улучшит ваши запросы к базе данных — не стесняйтесь этого.

person Cory R. King    schedule 25.02.2009
comment
2) верно в MySQL, если вы используете для этого столбца сопоставление без учета регистра (ci). MySQL также имеет некоторые сортировки с учетом регистра (cs). - person thomasrutter; 15.05.2009
comment
8.4 будет включать тип citext (текстовый тип без учета регистра) в качестве модуля contrib, который также доступен отдельно для 8.3: justatheory.com/computers/databases/postgresql/ - person araqnid; 15.05.2009

Если вы не соответствуете стандарту SQL92 при типизации столбцов, вы будете сталкиваться с различиями в именах типов между ними.

Модификация переменных в запросе не работает в postgreSQL, например, это будет работать в MySQL, но не в postgreSQL (я не проверял это недавно, возможно, сейчас это работает).

SET @a:=1 SELECT ID,@a:=@a+1 FROM some_table;

Я также лично считаю, что postgreSQL лучше обрабатывает сложные запросы, включающие подзапросы и тому подобное (которых раньше избегало большинство пользователей MySQL).

Редактировать: О, и я чуть не забыл! Способ, которым postgreSQL хранит таблицы, совершенно отличается от того, как это делает MySQL. Это также может повлиять на ваши стратегии резервного копирования/восстановления.

person Shalom Craimer    schedule 14.01.2009

Я не знаю, используете ли вы PHP или нет, но я обнаружил, что addlashes работает относительно хорошо для MySQL, но быстро бомбит в Postgres. Либо используйте pg_escape_string(), либо, что еще лучше, подготовленный оператор.

person gradbot    schedule 14.05.2009
comment
Теоретически вы не должны использовать addlashes() ни для того, ни для другого, хотя это имеет значение только тогда, когда вы используете кодировку, несовместимую с ascii. Любой ISO, ANSI, ASCII или UTF-8 безопасно использовать addlashes() в MySQL, но не что-то вроде UTF-16 или другого многобайтового кода. - person thomasrutter; 15.05.2009
comment
спасибо за совет по PHP, но, как я сказал в первом абзаце, мы используем REALbasic. - person Andy Dent; 17.05.2009

В зависимости от количества задействованных запросов (и если у вас есть кто-то, кто может это сделать), может быть целесообразно извлечь все запросы, адаптировать их по мере необходимости и запустить их на двух копиях существующей БД, на одной из которых работает mysql, а на другой — посгрел. Глядя на созданные журналы и сравнивая полученные данные, можно найти интересные подсказки. Первый шаг также может быть выполнен путем выполнения модульных тестов, ручного или скриптового тестирования приложения.

person MatthieuP    schedule 13.01.2009

Основываясь на сравнении WikiVS, я обнаружил ряд интересных моментов, большинство из которых не совсем верно, например как: - подзапросы намного быстрее в Postgres, на самом деле это не проблема, но означает, что некоторые обходные пути могут быть удалены

Этот сайт действительно привел меня к списку Postgres Gotchas, в котором было больше подробностей о скорость count(*) и другая проблема с последовательным сканированием: Max и Min являются последовательными сканированиями. Вероятность того, что это повредит нашей работе, гораздо больше, чем что-либо еще, выявленное до сих пор. Однако эта статья включает обходной путь Max(col):

SELECT col FROM table ORDER BY col DESC LIMIT 1
person Andy Dent    schedule 08.02.2009
comment
Обратите внимание на такие примечания, как Affects: PostgreSQL ‹= 8.0. Подсказка Max/min влияет на очень старые версии PostgreSQL, сегодня это не повлияет на вас. Большинство ошибок на странице устарели. Вот почему я не просто послал тебя туда. - person Tometzky; 09.02.2009
comment
Хорошо, спасибо, теперь я вижу, что это было исправлено в 8.1 postgresql .org/docs/8.1/interactive/release-8-1.html - person Andy Dent; 10.02.2009