Должен ли первичный ключ обязательно автоматически увеличиваться, когда я уверен, что он всегда будет уникальным?
Я некоторое время искал удовлетворительный ответ, более специфичный для моей конкретной проблемы, но безрезультатно. Я только не смотрю на правильные места или нет, я не знаю, но здесь идет:
Я извлекаю данные из приложения, которое впоследствии обрабатывается и отправляется на мой собственный сервер. Среди извлеченных данных есть, первоначально в базе данных приложения, автоинкрементный идентификатор. Примером этого идентификатора, который я только что получил, является 955534861. Разве это не лучший и более эффективный дизайн, чтобы не увеличивать автоматически мой первичный ключ и просто использовать значение, которое я знаю и всегда будет оставаться уникальным, или я должен рассмотреть такие понятия, как суррогатные ключи?
Заранее спасибо.
4 ответа
Ситуация, которую вы описываете, напоминает мою основную работу по обслуживанию хранилища данных. Мы получаем данные из других систем и храним их.
Что-то, что случается с нами, - то, что эти "другие системы" изменяются. Это приводит к тому, что новая версия "другой системы" будет дублировать уникальный идентификатор из предыдущей системы. Мы имеем дело с этим, добавляя что-то к этой записи в нашем хранилище данных, чтобы гарантировать ее уникальность. Это может быть поле для идентификации исходной системы или дата. Это никогда не является автоматически сгенерированным числом.
Если есть вероятность того, что это произойдет с вами, вы можете расширить свои возможности.
Если в вашей модели есть естественный ключ, вы не можете заменить его, создав суррогатный ключ.
Вы можете только добавить суррогатный ключ и сохранить существующий естественный ключ, который имеет свои плюсы и минусы, как описано здесь.
Это немного занудно, но терпите меня:
Пока значение ключа уникально, оно будет выполнять свою функцию. Но для производительности вы в идеале хотите, чтобы значение ключа было как можно более коротким.
Обычно используются идентификаторы GUID, поскольку статистически они вряд ли когда-либо будут повторяться. Но это происходит за счет размера: они имеют длину 128 бит, что делает их длиннее машинного слова. Для сравнения двух идентификаторов GUID (как это должно быть неоднократно сделано при сортировке или переносе вниз по b-дереву для индексов) потребуется несколько операций процессора для загрузки и сравнения значений. И они будут потреблять больше памяти при кэшировании в память.
Преимущество автоинкрементных значений ключа заключается в том, что
- Они гарантированно будут уникальными. Предполагается, что значения индекса прокси являются уникальными.
- Поскольку они будут иметь полное покрытие по всему диапазону своего базового типа данных, можно использовать наиболее компактный из возможных типов. Это делает для меньших индексов и более эффективных операций сравнения
- Поскольку можно использовать наименьший возможный тип, на одной странице базы данных можно сохранить больше значений индекса, что означает, что вы с большей вероятностью попадете в кэш при поиске или объединении этого значения. Это означает, что производительность будет - при прочих равных условиях - несколько лучше.
- В большинстве баз данных автоинкрементные ключи работают в ядре базы данных, поэтому при их создании накладные расходы очень малы.
- Если вы используете кластеризованный индекс для значения ключа, то для вставок новых записей менее вероятно потребуется случайный поиск на диске, и с большей вероятностью чтение во время опережающего чтения, поэтому если вы выполняете какую-либо последовательную обработку или поиск на основе этого ключа это, вероятно, будет работать быстрее.
Первичный ключ, как правило, с автоматическим приращением идентификатора, - это то, что MySQL также использует в качестве идентификатора строки, поэтому его следует оставить в покое. Если вам нужен вторичный ключ, сгенерированный вашим приложением для каких-то других целей, вы можете добавить его в качестве другого столбца с UNIQUE
Индекс на это.
В других базах данных, где есть правильный механизм идентификатора строки, это не проблема.