Запрос мнений: одна последовательность для всех таблиц - PullRequest
16 голосов
/ 08 октября 2009

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

Кто-нибудь видит какие-либо недостатки этого подхода. Я вижу только одно: в вашей базе данных не может быть более 999999999999999999999999999 записей.

Ответы [ 5 ]

11 голосов
/ 08 октября 2009

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

7 голосов
/ 08 октября 2009

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

Другая проблема - откат транзакций: последовательности не откатываются (потому что кто-то еще мог запросить более высокое значение), поэтому у вас могут быть большие пропуски, которые будут поглощать ваше числовое пространство гораздо быстрее, чем вы ожидаете. OTOH, потребуется некоторое время, чтобы съесть 2 или 4 миллиарда ID (если вы "только" используете 32-битные (подписанные) целые числа), поэтому на практике это редко возникает проблема.

Наконец, вы не можете легко сбросить последовательность, если это необходимо. Но если вам нужно иметь последовательность перезапуска (скажем, число записей с полуночи), вы можете указать Hibernate создать / использовать вторую последовательность.

Основным преимуществом является то, что вы можете однозначно идентифицировать объекты в любом месте БД только по идентификатору. Это означает, что вы можете существенно сократить информацию журнала, которую вы записываете в производственной системе, и все же найти что-то, если у вас есть только идентификатор.

5 голосов
/ 28 октября 2009

Я предпочитаю иметь одну последовательность на таблицу. Это вытекает из одного общего замечания: некоторые таблицы («основные таблицы») имеют относительно небольшое количество строк и должны храниться «навсегда». Например, таблица клиентов в ERP.

В других таблицах («таблицах транзакций») многие строки генерируются постоянно, но через некоторое время эти строки могут быть заархивированы (или просто удалены). Самый крайний пример - таблица трассировки, используемая для целей отладки; он может расти на сотни строк в секунду, но каждая строка устарела через несколько дней.

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

select * from orders where customerid=415

против

select * from orders where customerid=89461836571

Но это только незначительная проблема. Большая проблема - езда на велосипеде. Если вы используете одну последовательность для всех таблиц, вы просто не сможете перезапустить ее. Используя одну последовательность для каждой таблицы, вы можете перезапустить последовательности для таблиц транзакций, когда вы заархивировали или удалили старые данные. Главные таблицы вряд ли когда-либо сталкиваются с этой проблемой, поскольку они растут намного медленнее.

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

2 голосов
/ 28 октября 2009

Есть несколько недостатков использования одной последовательности: -

  • снижение параллелизма. Раздача следующего значения последовательности включает синхронизацию. На практике я не думаю, что это может быть большой проблемой
  • У Oracle есть специальный код для поддержки индексов btree, позволяющий обнаруживать монотонно растущие значения и уравновешивать баланс дерева.
  • CBO мог бы лучше оценить диапазон запросов к индексу (если вы когда-либо делали это), если бы большинство значений было заполнено

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

1 голос
/ 31 марта 2010

Конечно, есть плюсы и минусы подхода «одна последовательность против одной последовательности на таблицу». Лично я нахожу, что возможность назначать действительно уникальный идентификатор для строки, делая каждый столбец идентификатора UUID, достаточной для того, чтобы перевесить любые недостатки. Как лаконично пишет Аарон Д.:

вы можете однозначно идентифицировать объекты в любом месте БД просто по идентификатору

И, для большинства приложений, из-за того, что Hibernate3 упаковывает операторы IMPORT, это не будет узким местом в производительности, если огромное количество записей не соперничает за один и тот же ресурс БД (SELECT hibernate_sequence.nextval FROM dual).

Кроме того, это отображение последовательности не поддерживается в последней версии (1.2) Grails. Хотя это было поддержано в Grails 1.1 (!). В настоящее время требуется обходить подклассы одного из классов диалекта Hibernate.

Для тех, кто использует Grails / GORM, взгляните на эту запись JIRA:

Отображения последовательности Oracle игнорируются

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