Я знаю, что этот тип вопросов часто возникает, но мне еще предстоит прочитать убедительные аргументы, которые помогут мне принять это решение. Пожалуйста, потерпите меня!
У меня огромная база данных - она увеличивается примерно на 10 000 000 записей в день. Данные являются реляционными, и по соображениям производительности я загружаю таблицу с BULK COPY. По этой причине мне нужно генерировать ключи для строк, и я не могу полагаться на столбец IDENTITY.
64-разрядное целое число - bigint - достаточно широк, чтобы я мог его использовать, но чтобы гарантировать уникальность, мне нужен централизованный генератор, чтобы сделать свои идентификаторы для меня. В настоящее время у меня есть такая служба генератора, которая позволяет службе резервировать порядковые номера X и гарантирует отсутствие коллизий. Однако следствием этого является то, что все службы, которые у меня есть, зависят от этого одного централизованного генератора, и поэтому я ограничен в том, как я могу распределить свою систему, и не доволен другими зависимостями (такими как требование доступа к сети) этим дизайном. Это было проблемой по случаю.
Сейчас я рассматриваю возможность использования последовательных идентификаторов GUID в качестве моих первичных ключей (сгенерированных внешне для SQL). Насколько мне удалось выяснить из моего собственного тестирования, единственным недостатком для них являются издержки дискового пространства более широкого типа данных (что усугубляется их использованием в индексах). Я не наблюдал заметного снижения производительности запросов по сравнению с альтернативой bigint. Загрузка таблицы с помощью BULK COPY немного медленнее, но ненамного. Мои основанные на GUID индексы не становятся фрагментированными благодаря моей последовательной реализации GUID.
По сути, я хочу знать, есть ли какие-то другие соображения, которые я мог упустить из виду. На данный момент я склонен сделать прыжок и начать использовать GUID. Я ни в коем случае не эксперт по базам данных, поэтому я очень ценю любые рекомендации.
источник
Ответы:
Я в похожей ситуации. В настоящее время я использую последовательный подход GUID и не имею фрагментации и легкой генерации ключей.
Я заметил два недостатка, которые заставили меня начать переход на bigint:
(2) Был убийцей для меня.
Теперь я сгенерирую свои ключи так:
Я буду использовать ведущую дату плюс час, и после этого буду иметь последовательную часть . Это позволяет мне выполнять диапазонный запрос данных по дате без добавления индекса вообще. Это хороший бонус для меня.
Я сгенерирую последовательную часть bigint, используя алгоритм HiLo , который хорошо подходит для распространения .
Надеюсь, что некоторые из них переносятся в вашу ситуацию Я определенно рекомендую использовать bigint.
источник
С типом
INT
, начинающимся с 1, вы получаете более 2 миллиардов возможных строк - этого должно быть более чем достаточно для подавляющего большинства случаев. При этомBIGINT
вы получите примерно 922 квадриллиона (922 с 15 нулями - 922 000 миллиардов) - вам достаточно ??Если вы
INT IDENTITY
начинаете с 1 и вставляете строку каждую секунду, вам нужно 66,5 лет, прежде чем вы достигнете предела в 2 миллиарда ....Если вы
BIGINT IDENTITY
начинаете с 1 и вставляете тысячу строк каждую секунду, вам нужно ошеломить 292 миллиона лет, прежде чем вы достигнете предела в 922 квадриллиона ....Используя ваши 10 миллионов строк в день, у вас будет достаточно данных примерно для 1 844 667 407 380 дней ( 1844 миллиарда дней или 5 миллиардов лет ) - этого достаточно для ваших нужд. ?
Подробнее об этом (со всеми имеющимися опциями) читайте в MSDN Books Online .
источник
BIGINT
диапазон так быстро, хотя ....BIGINT IDENTITY
?Я рекомендую вам использовать SEQUENCE типа данных BIGINT в SQL 2012. Это гораздо более гибко, чем IDENTITY, с такими параметрами, как cache / nocache, вы также можете назначить диапазон последовательности для вашей пакетной операции как sp_sequence_get_range.
источник
Является ли причиной того, что вы не можете использовать IDENTITY, потому что между загружаемыми таблицами уже есть связи по внешнему ключу? И нет ли другого естественного ключа для вас, чтобы иметь возможность связать их в операции от промежуточного участка до производственного участка? По этой причине я хотел бы узнать немного больше о том, как они в настоящее время «связаны» в исходной системе, перед тем, как приступить к массовому копированию? Много ли исходные системы просто используют свои собственные последовательности и имеют возможность конфликтующих последовательностей при переносе в общую базу данных?
Мне знакома техника COMB ID / последовательный GUID, и она работоспособна в любое время, когда вам эффективно требуется глобальная уникальность, назначенная вне базы данных - это эффективно используемая идентификация строк как внутри, так и вне базы данных. По этой причине в сильно распределенных средах или отключенных сценариях это хороший выбор.
За исключением случаев, когда вам это действительно не нужно, потому что эта дополнительная разница в ширине значительна, когда размер данных увеличивается, и эти ключи присутствуют в каждом индексе и рабочих наборах для большого количества запросов.
Кроме того, при распределенной генерации, если строки на самом деле не располагаются в порядке столбца GUID, проблемы с использованием этого для ключа кластеризованного индекса (узкий, статический, увеличивающийся) могут вызвать некоторую фрагментацию по сравнению с кластеризацией на IDENTITY. остаются.
источник
В общем случае можно использовать
OUTPUT
пунктINSERT
команды, чтобы данные вставлялись в обе таблицы и были связаны с полем идентификации.Идентификатор, основанный на метке времени, не следует считать надежным - он зависит от системных часов, которые, в свою очередь, зависят от многих вещей - от аппаратных часов до сервисов синхронизации времени.
источник