Вопрос

Я знаю о полях ИДЕНТИФИКАЦИИ, но у меня такое чувство, что я не смог бы использовать их для решения своей проблемы.

Допустим, у меня есть несколько клиентов.У каждого клиента есть несколько заказов.Каждый клиент должен иметь последовательную нумерацию своих заказов, специфичную для него.

Пример структуры таблицы:

Orders:
OrderID | ClientID | ClientOrderID | etc...

Некоторыми примерами строк для этой таблицы могут быть:

OrderID | ClientID | ClientOrderID | etc...
1 | 1 | 1 | ...
2 | 1 | 2 | ...
3 | 2 | 1 | ...
4 | 3 | 1 | ...
5 | 1 | 3 | ...
6 | 2 | 2 | ...

Я знаю, что наивным способом было бы взять MAX ClientOrderID для любого клиента и использовать это значение для вставок, но это было бы связано с проблемами параллелизма.Я рассматривал возможность использования транзакции, но я не совсем уверен, какая самая широкая область изоляции может быть использована для этого.Я буду использовать LINQ для SQL, но у меня такое чувство, что это не имеет отношения к делу.

Это было полезно?

Решение

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

Таким образом, вы могли бы не делай

select @newOrderID=max(ClientOrderID) + 1
from orders
where clientid=@myClientID;

insert into ( ClientID, ClientOrderID, ...)
values( @myClientID, @newOrderID, ...);

Но ты может делай

insert into ( ClientID, ClientOrderID, ...)
select @myClientID, max(ClientOrderID) + 1, ...
from orders
where clientid=@myClientID;

Я предполагаю, что OrderID - это столбец идентификатора.

Опять же, если я ошибаюсь в этом, пожалуйста, дайте мне знать.Предпочтительно с URL-адресом

Другие советы

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

Шаблон репозитория: http://martinfowler.com/eaaCatalog/repository.html

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

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

Ваше предложение Max (ClientOrderID) прямолинейно и довольно легко реализовать (следуйте совету Джона Макинтайра).Вероятно, это будет приемлемо хорошо работать на столах с несколькими тысячами заказов.По мере роста таблицы этот подход, конечно, замедлится.

Предложение Ника Девора о таблице подстановки немного сложнее реализовать, но рост объема данных существенно не повлияет на него.

В зависимости от того, где / когда вам действительно нужен ClientOrderID, вы можете вычислить идентификатор, когда это необходимо, следующим образом:

SELECT *,
ROW_NUMBER() OVER(ORDER BY OrderID) AS ClientOrderID
FROM Orders
WHERE ClientID = 1

Это предполагает, что идентификаторы CLIENTORDERID находятся в той же последовательности, что и OrderID .Фактически не сохраняя идентификатор, его неудобно использовать в качестве ключа к чему-либо еще.Рост объема данных не должен повлиять на этот подход.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top