2012-03-10 25 views
6

Biorąc pod uwagę, że SQL Azure Federations nie obsługuje właściwości IDENTITY lub SEQUENCE, jaki byłby skuteczny sposób generowania kolejnych numerów podczas wstawiania rekordów?Wydajny sposób generowania liczb sekwencyjnych w federacjach SQL Azure

Na przykład, biorąc pod uwagę tabelę z tych kolumn:

CREATE TABLE [dbo].[Orders] (
    [TenantId] [uniqueidentifier] NOT NULL, 
    [OrderId] [uniqueidentifier] NOT NULL, 
    [OrderNumber] [int] NOT NULL 
    CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED (
     [TenantId] ASC, 
     [OrderId] ASC 
    ) 
) FEDERATED ON ([FederationKey] = [TenantId]) 

dla każdego zamówienia włożonej danego lokatora OrderID powinna być zwiększona. Na przykład dla namiotu A OrderId będzie 1, 2, 3 ... a dla najemcy B OrderId będzie również 1, 2, 3 ... w niezależnej sekwencji. Idealnie nie powinno być żadnych luk.

TenantId i OrderId są składowymi klucza podstawowego. Ich wartości są ustalane przez aplikację i nie są związane z kwestią generowania sekwencji; tylko OrderId ma numer kolejny o znaczeniu biznesowym. Ponadto TenantId jest kluczem dystrybucyjnym federacji.

This MSDN Blog article opisuje w opcji 1 podejście polegające na posiadaniu tabeli zawierającej sekwencje i stosowaniu procedury przechowywanej w segregowanej transakcji w celu zwiększenia sekwencji. Każdy lokator miałby rekord na tej tabeli zawierający ostatnią używaną wartość sekwencji.

Czy byłoby to optymalne podejście, biorąc pod uwagę skalowalność, rywalizację, blokowanie zasobów? Jakieś inne przydatne sztuczki, biorąc pod uwagę ograniczenia federacji SQL Azure?

Odpowiedz

2

Oto 2 dodatkowych pomysłów.

Podejście polegałoby na oddzielnej aktualizacji procesu w tym polu, aby było to asynchroniczne, o ile jest to możliwe w przypadku scenariusza biznesowego. Aby to podejście wymagało pola OrderNumber, zaakceptuj wartości NULL. Aby wiedzieć, które zamówienie było pierwsze, aby otrzymać prawidłowy numer zamówienia, dodałbym również pole InsertedDate. Przetwarzanie asynchroniczne staje się bardziej złożone, jeśli masz wiele ról roboczych wykonujących to zadanie dla nadmiarowości, w którym to przypadku będziesz musiał mieć każdy proces przypisany sobie do rekordów, nad którymi pracuje (więc potrzebujesz również pola OwnedBy), dodaj test współbieżności podczas UPDATE, aby upewnić się, że każdy proces jest wykonywany we własnych rekordach i ma przydzielone zadanie rekordów (więc również potrzebujesz pola AssignedOn), jeśli proces się zawiesi, aby nie opuszczał sierot. Niezbyt trywialne ...

A wtedy masz podejście człowieka ubogiego ... które, gdy gwiazdy wyrównują się wystarczająco dobrze, może być wszystkim, czego potrzebujesz. Jeśli chcesz mieć podejście optymistyczne do współbieżności, spróbuj użyć następnego Numeru podczas wstawiania (najpierw wybierz wartość Numer zlecenia MAX dla danego TenantId i OrderId), a następnie wykonaj Wstaw. Jeśli insert nie powiedzie się (ponieważ dodałeś indeks Unique na TenantId, OrderNumber w tym celu), po prostu dodaj 1 do OrderNumber. Prawdziwym problemem jest częstość prób i prawdopodobieństwo tego niepowodzenia. Jeśli masz względnie usprawniony proces biznesowy, może on nigdy nie zawieść; jeśli jednak zamówienia są stale dodawane z wielu ścieżek, może to stanowić niedopuszczalne podejście.

+0

Wielką odpowiedź, oprócz opcji przytoczyłem w moim pytaniu (przy użyciu procedury przechowywanej, aby zaktualizować rekord przy użyciu oddzielnego połączenia), pierwsza alternatywa zapewnia dużą skalowalność i przepustowość kosztem pewnej złożoności; druga alternatywa jest dość prosta i może wystarczyć, gdy proces zostanie usprawniony (np. za pomocą kolejki komunikatów) lub gdy tempo tworzenia nowych zamówień dla każdego lokatora nie jest zbyt wysokie. –

2

nie wiem, ile wysiłku będzie wymagane, aby pasowały do ​​scenariusza, ale spojrzeć na to jak dobrze i czy można go podkręcić: SnowMaker – a unique id generator for Azure (or any other cloud hosting environment)

+1

To świetny zasób. Dziękuję za zwrócenie mi uwagi.Lokalne grupowanie może być dość skuteczne i skalowalne, kosztem posiadania luk w kolejności i liczb poza porządkiem chronologicznym, co jest prawie w porządku dla wewnętrznych identyfikatorów, ale zwiększa (bezpodstawne) obawy, gdy są stosowane do numerów kontrolnych firmy. –

+0

Czy nadal zaleca się używanie tego? –