Были разные подобные вопросы, но они либо ссылались на слишком конкретную БД, либо предполагали несортированные данные.
В моем случае SQL должен быть переносимым, если это возможно.Указанный столбец индекса представляет собой кластеризованный PK, содержащий метку времени.
Метка времени на 99% больше времени, чем ранее вставленное значение.Однако в редких случаях он может быть меньше или конфликтовать с существующим значением.
В настоящее время я использую этот код для вставки новых значений:
IF NOT EXISTS (select * from Foo where Timestamp = @ts) BEGIN
INSERT INTO Foo ([Timestamp]) VALUES (@ts);
END
ELSE BEGIN
INSERT INTO Foo ([Timestamp]) VALUES (
(SELECT Max (t1.Timestamp) - 1
FROM Foo t1
WHERE Timestamp < @ts
AND NOT EXISTS (select * from Foo t2 where t2.Timestamp = t1.Timestamp - 1))
);
END;
Если строка еще не используетсяПросто вставьте.Иначе, найдите ближайшую свободную строку с меньшим значением, используя проверку EXISTS
.
Я новичок, когда дело доходит до баз данных, поэтому я не уверен, что есть лучший способ.Я открыт для любых идей, чтобы сделать код проще и / или быстрее (около 100-1000 вставок в секунду), или использовать другой подход в целом.
Редактировать Спасибо заВаши комментарии и ответы до сих пор.
Чтобы объяснить природу моего случая: отметка времени является единственным значением, когда-либо использованным для сортировки данных, незначительными несоответствиями можно пренебречь.Отношений ФК нет.
Однако я согласен с тем, что мой подход ошибочен, перевешивая причины использовать представленную идею в первую очередь.Если я правильно понимаю, простой способ исправить дизайн состоит в том, чтобы иметь регулярный автоинкрементный столбец PK в сочетании с известным (и переименованным) столбцом метки времени, который будет кластеризован.
Из POV производительности яне понимаю, как это может быть хуже, чем первоначальный подход.Это также значительно упрощает код.