Учитывая различные реализации последовательности / автоинкремента, как я могу создать оператор вставки SQL, который будет работать на разных rdbms? - PullRequest
5 голосов
/ 28 апреля 2011

Я пытаюсь создать метод для класса, который будет автоматически вставлять запись в таблицу. Проблема в том, что мне нужно, чтобы код работал для mysql, mssql, postgresql, oracle и sqlite.

Единственные решения, о которых я могу подумать:

  1. Создайте свои собственные значения первичного ключа, но это кажется очень рискованным, поскольку может быть трудно найти отказоустойчивое решение для генерации значений первичного ключа.

  2. Создайте код, который переключит используемый метод на основе используемого драйвера rdbms, но это выглядит неаккуратно, и я хотел бы использовать способ, совместимый со стандартами SQL, если это возможно.

Как я могу создать этот оператор INSERT для работы со всеми этими rdbms, если все они используют разные методы для автоматического увеличения поля первичного ключа?

Ответы [ 4 ]

5 голосов
/ 28 апреля 2011

Используйте специализированный код per-rdbms.

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

2 голосов
/ 28 апреля 2011

Нет ничего проблемного в вставке записей с полем автоинкремента: обычно вы просто пропускаете это поле во вставке, база данных генерирует его как вычисленное значение по умолчанию (поэтому оно называется «автоинкремент»).

Проблема переносимости возникает только тогда, когда вам нужно получить значение этого сгенерированного поля (которое часто является суррогатным первичным ключом). Не существует стандартного способа SQL для получения этого.

РЕДАКТИРОВАНИЕ: оук. Согласно комментариям относительно моего первого абзаца (второй абзац стоит):

Это правда, что не каждая база данных поддерживает прямые автоинкрементные поля "DEFAULT" (mea culpa). Однако, если вы предусмотрели схему схемы, которая поддерживает этот тип вставки (прямолинейно в Postgresql, Mysql, MSSQL и -Я думаю-SQLite; не прямой, но возможный -с триггерами- в Oracle), ТО вы можете кодировать свои SQL INSERTS простой и портативный способ. В другом месте вы не можете: в этом случае вы должны написать специфичные для rdbms INSERTS.

2 голосов
/ 28 апреля 2011

Чистый универсальный

Единственный гарантированный переносимый способ сделать это во всех мыслимых базах данных и иметь только одну единственную реализацию; чтобы приложение генерировало ключи как UUID s и вставляло их как обычные поля. Положительным моментом является то, что вам не нужно полагаться на какую-то конкретную языковую или библиотечную реализацию для получения ключа, он у вас уже есть.

Альтернативой UUID , если вы выполняете хранилище данных и не обновляете строки после того, как они INSERT ed, является криптографическим хэшем содержимого строки. Пусть ваше приложение объединит все содержимое полей в одну строку и извлечет хеш SHA1 этой строки. Этот ключ для всех практических целей гарантированно будет уникальным для этого содержимого. Также упрощает репликацию и поиск дубликатов.

Последовательные числа не являются окончанием всех первичных ключей.

UUID ключи легче переносить, и в 2011 году они бывают такими же быстрыми, когда индексация и место не должно быть проблемой, если у вас нет данных размера Facebook или Google, а затем у вас есть деньги на покупку дискового пространства, которое вам нужно, они также используют что-то, кроме числа long.

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

Универсальный SQL

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

PHP сделает поиск автоматически сгенерированных ключей проблематичным, если сделать это общим способом. Все, что я могу найти в этой теме, очень специализировано для любой используемой базы данных, и, похоже, нет общего API, эквивалентного JDBC для PHP.

Если вы использовали Java

Если вы используете логическое выполнение (String sql, int autoGeneratedKeys) в классе Statement . Вы можете сказать ему, в каком индексе поля находится автоматически сгенерированный ключ, и он вернет его, используя ResultSet getGeneratedKeys () .

Oracle Specific

Если вы установите значение DEFAULT в нужном поле автоинкремента в DDL для вызова функции, которая выбирает следующее значение из sequence, вы также можете реализовать желаемое поведение автоинкремента в Oracle.

Примечание

UUID иногда называют GUID и технически различны, но концептуально одно и то же.

0 голосов
/ 29 апреля 2011

Почему вы не используете ORM?В PHP их масса: Doctrine, Redbean и многие другие

Цель ORM - абстрагировать слой базы данных.Это звучит как то, что вам нужно.Ваш метод будет работать с объектами в вашем коде, а ORM имеет специальный код, необходимый для сохранения этих объектов в вашей базе данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...