Есть ли смысл создавать пользовательскую строку (комбинация сущности, года и буквенно-цифрового обозначения), чтобы иметь ее в качестве первичного ключа для базы данных postgres в Django?

Я работаю над созданием Django backend для приложения и хочу, чтобы первичный ключ наших сущностей соответствовал определенным критериям. Первый критерий - это то, что он всегда должен быть длиной 10 символов, чтобы его можно было легко прочитать и при необходимости передать устно. Второй критерий заключается в том, чтобы он всегда соответствовал одному и тому же формату:-

  1. Первые 2 символа => Код сущности (например, "US" - для записей пользователей, "TO" - для тем, "BO" - для книг и т.д.), чтобы любой мог легко сказать, для чего предназначен тот или иной идентификатор
  2. .
  3. Вторые 2 символа => Год даты создания ('24', '23 и т.д.)
  4. Оставшиеся 6 символов - случайно сгенерированные буквенно-цифровые символы

Я написал следующий код для генерации идентификатора:-

def auto_increment_id():

alphanumeric_chars = string.ascii_letters + string.digits
last_chars = ''.join(random.choice(alphanumeric_chars) for _ in range(6))
user_id = 'US' + str(datetime.date.today().year)[2:] + str(last_chars)
return user_id

А в модели пользователя я настроил это следующим образом

class User(models.Model):
id = models.CharField(max_length=10, primary_key=True,
                      default=auto_increment_id, editable=False)

Мой вопрос в том, приведет ли это к проблемам с производительностью или другим проблемам при увеличении масштаба? Является ли это разумной настройкой?

Есть проблемы с этой стратегией, помимо производительности.

Вы можете иметь только 36^6 возможных случайных строк из 6 буквенно-цифровых символов. На самом деле это близко к тому же количеству положительных значений в 4-байтовом целочисленном числе (PostgreSQL не поддерживает тип данных unsigned integer). Таким образом, использование целого числа вместо строки занимает на 1/3 меньше места.

Что произойдет, если ваша случайная шестизначная строка сгенерирует ту же строку, которая уже используется в другой строке? Это вызовет конфликт дублирующихся ключей, и вашему клиенту придется повторить попытку INSERT (возможно, не один раз). Очевидно, что такое случается редко, поскольку вероятность генерации одной и той же строки невелика. Но клиенту все равно придется обрабатывать эту потенциальную ошибку, поскольку нет гарантии, что она никогда не произойдет. Поэтому вам нужно написать больше кода для очень редких случаев. Не забудьте включить этот случай в ваши автоматические тесты.

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

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

  • Более компактный
  • Отсутствует вероятность случайного дублирования ключей
  • Поддерживаются модели Django

Мне кажется, вы пытаетесь решить проблему, для которой уже существует простое решение.

Вернуться на верх