SQL Best Practices - Хорошо полагаться на поле автоматического приращения для сортировки строк в хронологическом порядке?

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

Идея (простая) - сохранить накладные расходы/хранение и полагаться на первичный ключ для сортировки полей в хронологическом порядке. Уверен, что это работает, но я не уверен, приемлем этот подход в дизайне звуковой базы данных.

Плюсы: меньше хранения требуется на запись, более простые классы VO и т.д. и т.д.

Con: он подразумевает характеристику этого поля, в противном случае простой идентификатор, определение которого никоим образом не определяет или не гарантирует, что оно должно/будет функционировать как таковое.

Предположим ради моего вопроса, что определения таблицы БД заданы в камне. Тем не менее - это приемлемо с точки зрения лучших практик?

Спасибо

Ответ 1

Вы попросили "лучшие практики", а не "не страшные практики", поэтому: нет, вы не должны полагаться на автоинкрементный первичный ключ, чтобы установить хронологию. Однажды вы собираетесь внести изменения в дизайн db, и это сломается. Я видел, как это происходит.

Столбец datetime, значение по умолчанию которого GETDATE(), имеет очень мало накладных расходов (примерно столько же, сколько целое), и (еще лучше) говорит вам не просто последовательность, а фактическую дату и время, что часто оказывается бесценным. Даже поддержание индекса в столбце относительно дешево.

В эти дни я всегда помещал объекты данных столбца CreateDate, связанные с событиями реального мира (например, создание учетной записи).

Отредактировано для добавления:

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

Ответ 2

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

Есть несколько недостатков или ограничений, которые я вижу, однако.

  • Хронологическая сортировка может быть испорчена, если кто-то переделает столбец
  • Хронология для периода даты не может быть установлена ​​без дополнительных данных
  • Эта настройка не позволяет сортировать хронологически, если система когда-либо принимает новые, не хронологические данные.

Основываясь на реалистичной оценке этих "ограничений", вы должны быть в состоянии дать правильный подход.

Ответ 3

В дополнение к ответу egrunin изменение логики сохранения или обработки этих строк может привести к тому, что строки будут вставляться в базу данных несинхронным или недетерминированным образом. Вы можете реализовать параллельный файловый процессор, который выдает строку в БД, как только поток завершит преобразование, которое может быть до того, как другой поток завершит обработку строки, которая произошла ранее в файле. Использование ORM для сохранения записи может привести к аналогичному поведению; ORM может просто поддерживать "мешок" (неупорядоченный сбор) графиков объектов, ожидающих настойчивости, и захватывать их случайным образом, чтобы они сохраняли их в БД, когда он сказал "сбросить" свой буфер объекта.

В любом случае, доверяя столбцу автоинкремента, чтобы сообщить вам, в каком порядке записи в систему были плохой juju. Он может или не может указать вам порядок, в котором записывается его БАЗЫ ДАННЫХ; что зависит от реализации БД.

Ответ 4

Автоинкрементный идентификатор даст вам представление о заказе, как указывает Брэд, но сделайте это правильно - если вы хотите узнать, КОГДА что-то было добавлено, введите столбец datetime. Затем вы можете не только хронологически сортировать, но и применять фильтры.

Ответ 5

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

Вы говорите: "меньше памяти требуется для записи", но насколько это важно? Насколько велики строки, о которых мы говорим? Если у вас 200-байтовые строки, еще 4 байта, вероятно, не будут иметь большого значения.

Не оптимизируйте без измерения. Сначала запустите его, и ТОГДА оптимизируйте.

Ответ 6

@MadBreaker

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

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

Ответ 7

Вы не указали, работаете ли вы на одном db или кластеризованном. Если вы сгруппированы, будьте осторожны при реализации инкремента, так как вы не всегда гарантируете, что все будет в порядке, о котором вы, естественно, подумаете. Например, последовательности Oracle могут кэшировать группы следующих значений (в зависимости от вашей настройки) и дать вам список 1,3,2,4,5...