Czy powinienem zaimplementować automatyczne inkrementowanie w MongoDB?

Przełączam się na MongoDB z MySQL. Znana mi Architektura bardzo podstawowej tabeli users miałaby automatyczne inkrementowanie uid. Zobacz własną dokumentację Mongo dla tego przypadku użycia .

Zastanawiam się, czy to najlepsza decyzja architektoniczna. Z punktu widzenia UX lubię mieć UID jako zewnętrzne odniesienia, na przykład w krótszych adresach URL: http://example.com/users/12345 Czy istnieje trzecia droga? Ktoś w IRC Freenode ' S #mongodb zasugerował stworzenie zakresu identyfikatorów i ich buforowania. Nie jestem pewien, jak to właściwie wdrożyć, lub czy jest inna droga, którą mogę iść. Nie potrzebuję nawet samej _id, aby być zwiększonym w ten sposób. Tak długo, jak {[0] } wszystkie mają unikalną liczbę uid w dokumencie, byłbym szczęśliwy.
Author: Josh Smith, 2011-07-11

5 answers

Josh, Brak auto-increment id w MongoDB i są dobre powody. Powiedziałbym, że idź z obiektami, które są unikalne w klastrze.

Możesz dodać auto increment przez kolekcję sekwencji i używając findAndModify, aby uzyskać następny identyfikator do użycia. To z pewnością doda złożoności Twojej aplikacji, a także może wpłynąć na możliwość odłamania bazy danych.

Tak długo, jak możesz zagwarantować, że wygenerowane identyfikatory będą unikalne, wszystko będzie dobrze. Ale ból głowy będzie tam.

Możesz spojrzeć na ten post, aby uzyskać więcej informacji na temat tego pytania w dedykowanej grupie google dla MongoDB:

Http://groups.google.com/group/mongodb-user/browse_thread/thread/f57b712b2aae6f0b/b4315285e689b9a7?lnk=gst&q=projapati#b4315285e689b9a7

Mam nadzieję, że to pomoże.

Thanks

 21
Author: kheya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-11 05:03:36

Zdecydowanie nie zgadzam się z autorem wybranej odpowiedzi, że Brak auto-increment id w MongoDB i są dobre powody . Nie znamy powodów, dla których 10gen nie zachęcał do korzystania z autoakrementowanych identyfikatorów. To spekulacje. Myślę, że 10gen dokonał tego wyboru, ponieważ po prostu łatwiej jest zapewnić wyjątkowość 12-bajtowych identyfikatorów w środowisku klastrowym. Jest to domyślne rozwiązanie, które pasuje do większości nowo przybyłych, dlatego zwiększa przyjęcie produktu, co jest dobre dla biznesu 10gen.

Teraz pozwól mi powiedzieć wszyscy o moich doświadczeniach z obiektami w środowisku komercyjnym.

Buduję sieć społecznościową. Mamy około 6M użytkowników, a każdy użytkownik ma około 20 znajomych.

Teraz wyobraź sobie, że mamy kolekcję, która przechowuje relacje między użytkownikami(kto podąża za kim). Wygląda to tak

_id : ObjectId
user_id : ObjectId
followee_id : ObjectId

Na którym mamy unikalny indeks złożony {user_id, followee_id}. Możemy oszacować rozmiar tego indeksu na 12 * 2 * 6M*20 = 2GB. To indeks do szybkiego wyszukiwania ludzi, których śledzę. Do szybkiego wyszukiwania ludzie, którzy mnie śledzą, potrzebują odwróconego indeksu. To kolejne 2GB.

A to dopiero początek. Muszę nosić te dokumenty wszędzie. Mamy activity cluster, gdzie przechowujemy Twój kanał wiadomości. To każde wydarzenie, które robisz ty lub twoi przyjaciele. Wyobraź sobie, ile miejsca zajmuje.

I w końcu jeden z naszych inżynierów podjął nieświadomą decyzję i postanowił przechowywać odniesienia jako ciągi reprezentujące obiekt, który podwaja jego rozmiar.

Co się stanie, jeśli indeks nie pasuje do RAM? Nic dobrego, mówi 10gen:

gdy indeks jest zbyt duży, aby zmieścić się w pamięci RAM, MongoDB musi odczytać Indeks z dysku, co jest znacznie wolniejsze niż odczyt z pamięci RAM. Pamiętaj, że indeks pasuje do pamięci RAM, gdy serwer ma dostępną pamięć RAM dla indeksu w połączeniu z resztą zestawu roboczego.

To znaczy, że czytanie jest powolne. / Align = "left" / Pisze też wolniej. Oglądanie blokady w 80% nie jest już dla mnie szokiem.

Zanim się dowiesz skończyło się na klastrze 460gb, który musisz podzielić na odłamki i który jest dość trudny do manipulowania.

Facebook używa 64-bitowego identyfikatora użytkownika:) nie bez powodu. Możesz wygenerować sekwencyjne identyfikatory

  • za pomocą Rady 10gen .
  • używanie mysql jako magazynu liczników (jeśli zależy ci na szybkości spójrz na handlersocket)
  • używając usługi generowania ID zbudowałeś lub używając czegoś takiego jak Snowflake by Twitter.

Oto moja ogólna rada dla wszystkich. Prosimy, aby Twoje dane były jak najmniejsze. Kiedy rośnie to zaoszczędzi Ci wiele nieprzespanych nocy.

 93
Author: expert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-27 13:30:44

Istnieje więc podstawowy problem z identyfikatorami "auto-increment". Kiedy masz 10 różnych serwerów (shards w MongoDB), kto wybiera następny ID?

Jeśli chcesz pojedynczy zestaw identyfikatorów auto-inkrementujących, musisz mieć jeden autorytet do wybierania tych identyfikatorów. W MySQL jest to na ogół dość proste, ponieważ wystarczy jeden serwer akceptujący zapis. Ale wielkie wdrożenia MongoDB prowadzą sharding, który nie ma tej "władzy centralnej".

MongoDB, używa 12-bajtów ObjectIds tak, aby każdy serwer mógł tworzyć nowe dokumenty w sposób unikalny bez powoływania się na jeden organ.

Oto wielkie pytanie: "czy stać Cię na posiadanie jednego autorytetu"?

Jeśli tak, to możesz użyć findAndModify, aby śledzić "ostatni najwyższy IDENTYFIKATOR", a następnie możesz go wstawić.

To proces opisany w twoim linku. Oczywistą słabością jest to, że technicznie musisz zrobić dwa zapisy dla każdej wkładki. To może nie skalować się zbyt dobrze, prawdopodobnie chcesz tego uniknąć na danych z wysoką szybkością wstawiania. Może działać dla użytkowników, prawdopodobnie nie będzie działać dla śledzenia kliknięć.

 17
Author: Gates VP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-23 20:47:46

Nie ma to jak auto-przyrost w MongoDB, ale możesz przechowywać własne liczniki w dedykowanej kolekcji I $inc powiązaną wartość licznika w razie potrzeby. Ponieważ $inc jest operacją atomową, nie zobaczysz duplikatów.

 12
Author: Andreas Jung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-11 04:11:07

Domyślny obiekt Mongo -- ten używany w polu _id -- jest inkrementowany.

Mongo używa znacznika czasu (sekund od epoki Uniksa) jako pierwszej 4-bajtowej części swojej kompozycji 4-3-2-3, bardzo podobnej (jeśli nie dokładnie) tej samej kompozycji co uuid w wersji 1. I że ObjectId jest generowany w momencie Wstawienia (jeśli użytkownik/klient nie dostarczy innego typu _id)

Tak więc obiekt ma charakter porządkowy; ponadto domyślne sortowanie opiera się na tym zwiększaniu znacznik czasu.

Można uznać to za zaktualizowaną wersję identyfikatorów auto-inkrementacji (index++) używanych w wielu systemach dbms.

 4
Author: Gabe Rainbow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 04:21:22