{"id":1361,"date":"2026-04-03T13:02:55","date_gmt":"2026-04-03T11:02:55","guid":{"rendered":"https:\/\/trzykody.pl\/?p=1361"},"modified":"2026-04-20T13:08:03","modified_gmt":"2026-04-20T11:08:03","slug":"mapowanie-identyfikatorow","status":"publish","type":"post","link":"https:\/\/trzykody.pl\/index.php\/2026\/04\/03\/mapowanie-identyfikatorow\/","title":{"rendered":"Mapowanie identyfikator\u00f3w"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">System informatyczny bardzo rzadko dzia\u0142a w ca\u0142kowitej izolacji. Dane przechodz\u0105 mi\u0119dzy baz\u0105 danych, panelem administracyjnym, systemem ksi\u0119gowym, API partnera, modu\u0142em magazynowym i raportowaniem. W ka\u017cdym z tych miejsc ten sam obiekt &#8211; u\u017cytkownik, zam\u00f3wienie, produkt albo faktura &#8211; mo\u017ce mie\u0107 inny identyfikator. Je\u015bli nie zostanie zachowana sp\u00f3jno\u015b\u0107 tych powi\u0105za\u0144, pojawiaj\u0105 si\u0119 duplikaty, b\u0142\u0119dne rozliczenia i trudne do wykrycia b\u0142\u0119dy logiczne. W praktyce w\u0142a\u015bnie temu s\u0142u\u017cy <strong>Mapowanie identyfikator\u00f3w<\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Spis Tre\u015bci<\/h2><nav><ol><li><a href=\"#mapowanie-identyfikatorow-w-bazach-danych-i-systemach-rozproszonych-wymaga-kontroli-spojnosci-oraz-przewidywalnych-regul-synchronizacji\">Mapowanie identyfikator\u00f3w w bazach danych i systemach rozproszonych wymaga kontroli sp\u00f3jno\u015bci oraz przewidywalnych regu\u0142 synchronizacji<\/a><ol><li><a href=\"#tabela-powiazan-jako-osobna-warstwa-logiki\">Tabela powi\u0105za\u0144 jako osobna warstwa logiki<\/a><\/li><li><a href=\"#przyklad-sql-w-stylu-prostym-i-czytelnym\">Przyk\u0142ad SQL w stylu prostym i czytelnym<\/a><\/li><li><a href=\"#problem-duplikatow-podczas-importu\">Problem duplikat\u00f3w podczas importu<\/a><\/li><\/ol><\/li><li><a href=\"#mapowanie-identyfikatorow-podczas-integracji-api-wymaga-odpornosci-na-bledy-sieciowe-oraz-niejednoznacznosc-danych-wejsciowych\">Mapowanie identyfikator\u00f3w podczas integracji API wymaga odporno\u015bci na b\u0142\u0119dy sieciowe oraz niejednoznaczno\u015b\u0107 danych wej\u015bciowych<\/a><ol><li><a href=\"#przyklad-w-python\">Przyk\u0142ad w Python<\/a><\/li><li><a href=\"#przyklad-w-c\">Przyk\u0142ad w C++<\/a><\/li><li><a href=\"#przyklad-w-c-1\">Przyk\u0142ad w C<\/a><\/li><li><a href=\"#idempotencja-jako-zabezpieczenie-praktyczne\">Idempotencja jako zabezpieczenie praktyczne<\/a><\/li><\/ol><\/li><li><a href=\"#mapowanie-identyfikatorow-a-wydajnosc-wyszukiwania-zalezy-od-struktury-danych-indeksow-oraz-sposobu-aktualizacji-rekordow\">Mapowanie identyfikator\u00f3w a wydajno\u015b\u0107 wyszukiwania zale\u017cy od struktury danych, indeks\u00f3w oraz sposobu aktualizacji rekord\u00f3w<\/a><ol><li><a href=\"#wzor-opisujacy-koszt-wyszukiwania-liniowego\">Wz\u00f3r opisuj\u0105cy koszt wyszukiwania liniowego<\/a><\/li><li><a href=\"#wzor-przy-wyszukiwaniu-logarytmicznym\">Wz\u00f3r przy wyszukiwaniu logarytmicznym<\/a><\/li><li><a href=\"#praktyczne-zasady-projektowe\">Praktyczne zasady projektowe<\/a><\/li><\/ol><\/li><li><a href=\"#najczestsze-bledy-praktyczne-i-miejsca-w-ktorych-system-zaczyna-generowac-koszt-zamiast-porzadku\">Najcz\u0119stsze b\u0142\u0119dy praktyczne i miejsca, w kt\u00f3rych system zaczyna generowa\u0107 koszt zamiast porz\u0105dku<\/a><\/li><li><a href=\"#faq\">FAQ<\/a><ol><li><a href=\"#czy-uuid-zawsze-jest-lepszy-od-zwyklego-int\">Czy UUID zawsze jest lepszy od zwyk\u0142ego INT?<\/a><\/li><li><a href=\"#czy-klucz-biznesowy-moze-byc-kluczem-glownym\">Czy klucz biznesowy mo\u017ce by\u0107 kluczem g\u0142\u00f3wnym?<\/a><\/li><li><a href=\"#czy-tabela-translacji-jest-potrzebna-w-malym-systemie\">Czy tabela translacji jest potrzebna w ma\u0142ym systemie?<\/a><\/li><li><a href=\"#co-zrobic-po-wykryciu-duplikatow\">Co zrobi\u0107 po wykryciu duplikat\u00f3w?<\/a><\/li><li><a href=\"#czy-warto-logowac-kazde-powiazanie\">Czy warto logowa\u0107 ka\u017cde powi\u0105zanie?<\/a><\/li><\/ol><\/li><\/ol><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"mapowanie-identyfikatorow-w-bazach-danych-i-systemach-rozproszonych-wymaga-kontroli-spojnosci-oraz-przewidywalnych-regul-synchronizacji\">Mapowanie identyfikator\u00f3w w bazach danych i systemach rozproszonych wymaga kontroli sp\u00f3jno\u015bci oraz przewidywalnych regu\u0142 synchronizacji<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Najprostszy przypadek to relacyjna baza danych, gdzie rekord klienta ma klucz g\u0142\u00f3wny <code>id = 125<\/code>. Problem zaczyna si\u0119 wtedy, gdy ten sam klient trafia do CRM, hurtowni danych i systemu zewn\u0119trznego, gdzie wyst\u0119puje jako <code>customer_id = A-9912<\/code> albo <code>uuid = 8f2b...<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nie chodzi tylko o zapis warto\u015bci. Trzeba zagwarantowa\u0107, \u017ce relacja b\u0119dzie trwa\u0142a, jednoznaczna i odporna na b\u0142\u0119dy synchronizacji.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Najcz\u0119\u015bciej spotykane typy identyfikator\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>klucz techniczny (<code>INT<\/code>, <code>BIGINT<\/code>, <code>UUID<\/code>)<\/li>\n\n\n\n<li>klucz biznesowy (NIP, numer zam\u00f3wienia, numer klienta)<\/li>\n\n\n\n<li>identyfikator zewn\u0119trzny nadany przez API partnera<\/li>\n\n\n\n<li>identyfikator tymczasowy u\u017cywany podczas importu danych<\/li>\n\n\n\n<li>identyfikator po\u015bredni u\u017cywany w migracjach<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Klucz techniczny jest wygodny dla bazy danych, ale zwykle nic nie znaczy biznesowo. Klucz biznesowy jest czytelny dla cz\u0142owieka, ale mo\u017ce si\u0119 zmienia\u0107 lub nie by\u0107 unikalny globalnie. Dlatego systemy produkcyjne bardzo cz\u0119sto u\u017cywaj\u0105 obu jednocze\u015bnie.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"tabela-powiazan-jako-osobna-warstwa-logiki\">Tabela powi\u0105za\u0144 jako osobna warstwa logiki<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Dobrym rozwi\u0105zaniem jest osobna tabela translacji identyfikator\u00f3w zamiast nadpisywania danych w g\u0142\u00f3wnej tabeli.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Element<\/th><th>Przyk\u0142ad<\/th><\/tr><\/thead><tbody><tr><td>lokalny identyfikator<\/td><td><code>user_id = 125<\/code><\/td><\/tr><tr><td>system \u017ar\u00f3d\u0142owy<\/td><td><code>erp_system<\/code><\/td><\/tr><tr><td>identyfikator zewn\u0119trzny<\/td><td><code>ERP-88421<\/code><\/td><\/tr><tr><td>data synchronizacji<\/td><td><code>2026-04-20 10:30:00<\/code><\/td><\/tr><tr><td>status<\/td><td>aktywny \/ archiwalny<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Taki model pozwala:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>obs\u0142u\u017cy\u0107 wiele \u017ar\u00f3de\u0142 dla jednego rekordu<\/li>\n\n\n\n<li>zachowa\u0107 histori\u0119 zmian<\/li>\n\n\n\n<li>\u0142atwiej diagnozowa\u0107 b\u0142\u0119dy integracyjne<\/li>\n\n\n\n<li>unikn\u0105\u0107 problem\u00f3w podczas migracji<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"przyklad-sql-w-stylu-prostym-i-czytelnym\">Przyk\u0142ad SQL w stylu prostym i czytelnym<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>SQL<\/td><td><code>sql CREATE TABLE user_mapping ( id INT PRIMARY KEY AUTO_INCREMENT, local_user_id INT NOT NULL, source_system VARCHAR(50) NOT NULL, external_user_id VARCHAR(100) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE (source_system, external_user_id) );<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Klucz unikalny na <code>(source_system, external_user_id)<\/code> zabezpiecza przed sytuacj\u0105, w kt\u00f3rej dwa r\u00f3\u017cne rekordy lokalne pr\u00f3buj\u0105 wskazywa\u0107 na ten sam rekord zewn\u0119trzny.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"problem-duplikatow-podczas-importu\">Problem duplikat\u00f3w podczas importu<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To jeden z najdro\u017cszych b\u0142\u0119d\u00f3w operacyjnych. Je\u015bli import klient\u00f3w zostanie uruchomiony dwa razy bez poprawnego sprawdzenia istniej\u0105cych powi\u0105za\u0144, system mo\u017ce wygenerowa\u0107 dwa konta dla jednej osoby.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W praktyce skutki bywaj\u0105 kosztowne:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>podw\u00f3jna wysy\u0142ka towaru<\/li>\n\n\n\n<li>b\u0142\u0119dne naliczenie rabatu<\/li>\n\n\n\n<li>rozjazd stan\u00f3w magazynowych<\/li>\n\n\n\n<li>b\u0142\u0119dne raporty finansowe<\/li>\n\n\n\n<li>reklamacje klient\u00f3w<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Koszt naprawy r\u0119cznej jest zwykle wielokrotnie wi\u0119kszy ni\u017c koszt poprawnego projektu na pocz\u0105tku.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"mapowanie-identyfikatorow-podczas-integracji-api-wymaga-odpornosci-na-bledy-sieciowe-oraz-niejednoznacznosc-danych-wejsciowych\">Mapowanie identyfikator\u00f3w podczas integracji API wymaga odporno\u015bci na b\u0142\u0119dy sieciowe oraz niejednoznaczno\u015b\u0107 danych wej\u015bciowych<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Integracja z API wygl\u0105da dobrze tylko na diagramie. W rzeczywisto\u015bci pojawiaj\u0105 si\u0119 timeouty, cz\u0119\u015bciowe odpowiedzi, zmiany schematu i b\u0142\u0119dy po stronie partnera.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Za\u0142\u00f3\u017cmy, \u017ce lokalny sklep wysy\u0142a zam\u00f3wienie do firmy kurierskiej. Po poprawnym utworzeniu przesy\u0142ki zewn\u0119trzny system zwraca numer:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Pole<\/th><th>Warto\u015b\u0107<\/th><\/tr><\/thead><tbody><tr><td>local_order_id<\/td><td><code>5021<\/code><\/td><\/tr><tr><td>shipment_id<\/td><td><code>SHIP-778811<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Ten numer musi zosta\u0107 zapisany natychmiast i atomowo. Je\u015bli zapis si\u0119 nie powiedzie, system mo\u017ce ponownie wys\u0142a\u0107 to samo zam\u00f3wienie i wygenerowa\u0107 kolejn\u0105 przesy\u0142k\u0119.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"przyklad-w-python\">Przyk\u0142ad w Python<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>python orders = {5021: None} external_id = \"SHIP-778811\" if orders[5021] is None: orders[5021] = external_id print(orders)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Kod jest prosty, ale pokazuje podstawow\u0105 zasad\u0119: najpierw sprawdzenie istniej\u0105cego powi\u0105zania, potem zapis.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"przyklad-w-c\">Przyk\u0142ad w C++<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>C++<\/td><td><code>cpp #include &lt;iostream&gt; #include &lt;map&gt; using namespace std; int main() { map&lt;int, string&gt; orders; orders[5021] = \"\"; if (orders[5021].empty()) { orders[5021] = \"SHIP-778811\"; } cout &lt;&lt; orders[5021] &lt;&lt; endl; return 0; }<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"przyklad-w-c-1\">Przyk\u0142ad w C<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>C<\/td><td><code>c #include &lt;stdio.h&gt; #include &lt;string.h&gt; int main() { int local_id = 5021; char external_id[20] = \"\"; if (strlen(external_id) == 0) { strcpy(external_id, \"SHIP-778811\"); } printf(\"%d -&gt; %s\\n\", local_id, external_id); return 0; }<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"idempotencja-jako-zabezpieczenie-praktyczne\">Idempotencja jako zabezpieczenie praktyczne<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u017celi ta sama operacja zostanie wykonana dwa razy, wynik powinien pozosta\u0107 taki sam.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To bardzo wa\u017cne przy:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>p\u0142atno\u015bciach<\/li>\n\n\n\n<li>zam\u00f3wieniach<\/li>\n\n\n\n<li>wysy\u0142kach<\/li>\n\n\n\n<li>generowaniu faktur<\/li>\n\n\n\n<li>synchronizacji stan\u00f3w magazynowych<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Bez tego jedna awaria sieci mo\u017ce stworzy\u0107 realn\u0105 strat\u0119 finansow\u0105.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Najcz\u0119\u015bciej stosuje si\u0119:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>klucz idempotencyjny<\/li>\n\n\n\n<li>blokad\u0119 transakcyjn\u0105<\/li>\n\n\n\n<li>zapis w kolejce zdarze\u0144<\/li>\n\n\n\n<li>kontrol\u0119 unikalno\u015bci po stronie bazy<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"mapowanie-identyfikatorow-a-wydajnosc-wyszukiwania-zalezy-od-struktury-danych-indeksow-oraz-sposobu-aktualizacji-rekordow\">Mapowanie identyfikator\u00f3w a wydajno\u015b\u0107 wyszukiwania zale\u017cy od struktury danych, indeks\u00f3w oraz sposobu aktualizacji rekord\u00f3w<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Przy ma\u0142ej skali wszystko dzia\u0142a szybko. Problem pojawia si\u0119 przy milionach rekord\u00f3w.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u015bli tabela translacji ma 20 milion\u00f3w wpis\u00f3w, a ka\u017cde zapytanie wykonuje pe\u0142ne skanowanie, op\u00f3\u017anienia rosn\u0105 gwa\u0142townie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przybli\u017cone r\u00f3\u017cnice:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Operacja<\/th><th>Z\u0142o\u017cono\u015b\u0107<\/th><\/tr><\/thead><tbody><tr><td>wyszukiwanie liniowe w li\u015bcie<\/td><td>O(n)<\/td><\/tr><tr><td>wyszukiwanie w drzewie zbalansowanym<\/td><td>O(log n)<\/td><\/tr><tr><td>tablica haszuj\u0105ca \u015brednio<\/td><td>O(1)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To nie jest teoria akademicka. Przy 10 rekordach r\u00f3\u017cnica jest niewidoczna. Przy 10 milionach oznacza sekundy albo milisekundy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wzor-opisujacy-koszt-wyszukiwania-liniowego\">Wz\u00f3r opisuj\u0105cy koszt wyszukiwania liniowego<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Zastosowanie<\/th><th>Wz\u00f3r<\/th><\/tr><\/thead><tbody><tr><td>\u015brednia liczba por\u00f3wna\u0144<\/td><td><code>n \/ 2<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>f<\/mi><mo stretchy=\"false\">(<\/mo><mi>n<\/mi><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mi>n<\/mi><mn>2<\/mn><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">f(n)=\\frac{n}{2}<\/annotation><\/semantics><\/math>f(n)=2n\u200b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dla miliona rekord\u00f3w \u015brednio potrzeba oko\u0142o 500 000 por\u00f3wna\u0144. To ju\u017c realny koszt procesora i czasu odpowiedzi.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wzor-przy-wyszukiwaniu-logarytmicznym\">Wz\u00f3r przy wyszukiwaniu logarytmicznym<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Zastosowanie<\/th><th>Wz\u00f3r<\/th><\/tr><\/thead><tbody><tr><td>liczba krok\u00f3w<\/td><td><code>log2(n)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>f<\/mi><mo stretchy=\"false\">(<\/mo><mi>n<\/mi><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><msub><mrow><mi>log<\/mi><mo>\u2061<\/mo><\/mrow><mn>2<\/mn><\/msub><mo stretchy=\"false\">(<\/mo><mi>n<\/mi><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">f(n)=\\log_2(n)<\/annotation><\/semantics><\/math>f(n)=log2\u200b(n)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dla miliona rekord\u00f3w to oko\u0142o 20 krok\u00f3w zamiast setek tysi\u0119cy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"praktyczne-zasady-projektowe\">Praktyczne zasady projektowe<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>indeksuj kolumny u\u017cywane do wyszukiwania<\/li>\n\n\n\n<li>nie u\u017cywaj zmiennych identyfikator\u00f3w jako klucza g\u0142\u00f3wnego<\/li>\n\n\n\n<li>rozdziel klucz techniczny od biznesowego<\/li>\n\n\n\n<li>zapisuj \u017ar\u00f3d\u0142o pochodzenia danych<\/li>\n\n\n\n<li>loguj b\u0142\u0119dy synchronizacji<\/li>\n\n\n\n<li>nie zak\u0142adaj, \u017ce system zewn\u0119trzny jest zawsze poprawny<\/li>\n\n\n\n<li>przygotuj procedur\u0119 r\u0119cznej naprawy relacji<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Brak punktu 7 jest cz\u0119sty. Gdy integracja si\u0119 psuje, zesp\u00f3\u0142 cz\u0119sto nie ma narz\u0119dzia do bezpiecznej korekty danych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"najczestsze-bledy-praktyczne-i-miejsca-w-ktorych-system-zaczyna-generowac-koszt-zamiast-porzadku\">Najcz\u0119stsze b\u0142\u0119dy praktyczne i miejsca, w kt\u00f3rych system zaczyna generowa\u0107 koszt zamiast porz\u0105dku<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Pierwszy b\u0142\u0105d to u\u017cywanie adresu e-mail jako jedynego klucza. U\u017cytkownik mo\u017ce go zmieni\u0107, mo\u017ce mie\u0107 kilka adres\u00f3w albo wsp\u00f3\u0142dzielony adres firmowy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Drugi b\u0142\u0105d to brak historii zmian. Je\u015bli identyfikator zewn\u0119trzny zostanie zmieniony przez partnera, system bez historii traci mo\u017cliwo\u015b\u0107 audytu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Trzeci b\u0142\u0105d to synchronizacja \u201ena skr\u00f3ty\u201d, czyli r\u0119czne dopisywanie warto\u015bci bez walidacji. To zwykle ko\u0144czy si\u0119 trudnym do odtworzenia stanem danych.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Czwarty b\u0142\u0105d to brak transakcji. Je\u015bli zapis lokalny si\u0119 powiedzie, ale zapis relacji nie \u2014 system staje si\u0119 niesp\u00f3jny.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pi\u0105ty b\u0142\u0105d to nadmierne zaufanie do danych wej\u015bciowych. Integracja powinna zak\u0142ada\u0107, \u017ce dane zewn\u0119trzne bywaj\u0105 b\u0142\u0119dne.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-uuid-zawsze-jest-lepszy-od-zwyklego-int\">Czy UUID zawsze jest lepszy od zwyk\u0142ego INT?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nie zawsze. UUID daje wi\u0119ksz\u0105 unikalno\u015b\u0107 globaln\u0105 i dobrze dzia\u0142a w systemach rozproszonych, ale zajmuje wi\u0119cej miejsca i mo\u017ce pogarsza\u0107 wydajno\u015b\u0107 indeks\u00f3w. Dla prostych system\u00f3w lokalnych <code>INT<\/code> cz\u0119sto jest lepszy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-klucz-biznesowy-moze-byc-kluczem-glownym\">Czy klucz biznesowy mo\u017ce by\u0107 kluczem g\u0142\u00f3wnym?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Technicznie tak, ale zwykle nie warto. Je\u015bli numer klienta lub NIP si\u0119 zmieni, aktualizacja staje si\u0119 kosztowna i ryzykowna. Lepiej u\u017cywa\u0107 osobnego klucza technicznego.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-tabela-translacji-jest-potrzebna-w-malym-systemie\">Czy tabela translacji jest potrzebna w ma\u0142ym systemie?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u015bli system ma tylko jedn\u0105 baz\u0119 i nie komunikuje si\u0119 z niczym zewn\u0119trznym, cz\u0119sto nie. Gdy pojawia si\u0119 API, ERP albo migracja danych &#8211; staje si\u0119 bardzo przydatna.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"co-zrobic-po-wykryciu-duplikatow\">Co zrobi\u0107 po wykryciu duplikat\u00f3w?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Najpierw ustali\u0107 \u017ar\u00f3d\u0142o problemu, potem zablokowa\u0107 dalsze powstawanie b\u0142\u0119du. Dopiero p\u00f3\u017aniej scala\u0107 dane. R\u0119czne usuwanie rekord\u00f3w bez analizy zwykle pogarsza sytuacj\u0119.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-warto-logowac-kazde-powiazanie\">Czy warto logowa\u0107 ka\u017cde powi\u0105zanie?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tak, szczeg\u00f3lnie przy operacjach finansowych i magazynowych. Koszt miejsca jest zwykle ma\u0142y w por\u00f3wnaniu z czasem potrzebnym na analiz\u0119 awarii bez historii zdarze\u0144.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dobrze zaprojektowana warstwa translacji identyfikator\u00f3w nie jest dodatkiem technicznym, tylko elementem bezpiecze\u0144stwa danych. To ona decyduje, czy po kilku miesi\u0105cach system nadal da si\u0119 kontrolowa\u0107, czy zaczyna dzia\u0142a\u0107 wy\u0142\u0105cznie \u201ebo jeszcze si\u0119 nie zepsu\u0142\u201d.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>\u0179r\u00f3d\u0142o Foto: Freepik<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>System informatyczny bardzo rzadko dzia\u0142a w ca\u0142kowitej izolacji. Dane przechodz\u0105 mi\u0119dzy baz\u0105 danych, panelem administracyjnym, systemem ksi\u0119gowym, API partnera, modu\u0142em magazynowym i raportowaniem. W ka\u017cdym z tych miejsc ten sam obiekt &#8211; u\u017cytkownik, zam\u00f3wienie, produkt albo faktura &#8211; mo\u017ce mie\u0107 inny identyfikator. Je\u015bli nie zostanie zachowana sp\u00f3jno\u015b\u0107 tych powi\u0105za\u0144, pojawiaj\u0105 si\u0119 duplikaty, b\u0142\u0119dne rozliczenia i trudne do wykrycia b\u0142\u0119dy logiczne. W praktyce w\u0142a\u015bnie temu s\u0142u\u017cy Mapowanie identyfikator\u00f3w. Mapowanie identyfikator\u00f3w w bazach danych i systemach rozproszonych wymaga kontroli sp\u00f3jno\u015bci oraz przewidywalnych regu\u0142 synchronizacji Najprostszy przypadek to relacyjna baza danych, gdzie rekord klienta ma klucz g\u0142\u00f3wny id = 125. Problem zaczyna si\u0119 wtedy, gdy ten sam klient trafia do CRM, hurtowni danych i systemu zewn\u0119trznego, gdzie wyst\u0119puje jako customer_id = A-9912 albo uuid = 8f2b&#8230;. Nie chodzi tylko o zapis warto\u015bci. Trzeba zagwarantowa\u0107, \u017ce relacja b\u0119dzie trwa\u0142a, jednoznaczna i odporna na b\u0142\u0119dy synchronizacji. Najcz\u0119\u015bciej spotykane typy identyfikator\u00f3w: Klucz techniczny jest wygodny dla bazy danych, ale zwykle nic nie znaczy biznesowo. Klucz biznesowy jest czytelny dla cz\u0142owieka, ale mo\u017ce si\u0119 zmienia\u0107 lub nie by\u0107 unikalny globalnie. Dlatego systemy produkcyjne bardzo cz\u0119sto u\u017cywaj\u0105 obu jednocze\u015bnie. Tabela powi\u0105za\u0144 jako osobna warstwa logiki Dobrym rozwi\u0105zaniem jest osobna tabela translacji identyfikator\u00f3w zamiast nadpisywania danych w g\u0142\u00f3wnej tabeli. Element Przyk\u0142ad lokalny identyfikator user_id = 125 system \u017ar\u00f3d\u0142owy erp_system identyfikator zewn\u0119trzny ERP-88421 data synchronizacji 2026-04-20 10:30:00 status aktywny \/ archiwalny Taki model pozwala: Przyk\u0142ad SQL w stylu prostym i czytelnym J\u0119zyk Kod SQL sql CREATE TABLE user_mapping ( id INT PRIMARY KEY AUTO_INCREMENT, local_user_id INT NOT NULL, source_system VARCHAR(50) NOT NULL, external_user_id VARCHAR(100) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE (source_system, external_user_id) ); Klucz unikalny na (source_system, external_user_id) zabezpiecza przed sytuacj\u0105, w kt\u00f3rej dwa r\u00f3\u017cne rekordy lokalne pr\u00f3buj\u0105 wskazywa\u0107 na ten sam rekord zewn\u0119trzny. Problem duplikat\u00f3w podczas importu To jeden z najdro\u017cszych b\u0142\u0119d\u00f3w operacyjnych. Je\u015bli import klient\u00f3w zostanie uruchomiony dwa razy bez poprawnego sprawdzenia istniej\u0105cych powi\u0105za\u0144, system mo\u017ce wygenerowa\u0107 dwa konta dla jednej osoby. W praktyce skutki bywaj\u0105 kosztowne: Koszt naprawy r\u0119cznej jest zwykle wielokrotnie wi\u0119kszy ni\u017c koszt poprawnego projektu na pocz\u0105tku. Mapowanie identyfikator\u00f3w podczas integracji API wymaga odporno\u015bci na b\u0142\u0119dy sieciowe oraz niejednoznaczno\u015b\u0107 danych wej\u015bciowych Integracja z API wygl\u0105da dobrze tylko na diagramie. W rzeczywisto\u015bci pojawiaj\u0105 si\u0119 timeouty, cz\u0119\u015bciowe odpowiedzi, zmiany schematu i b\u0142\u0119dy po stronie partnera. Za\u0142\u00f3\u017cmy, \u017ce lokalny sklep wysy\u0142a zam\u00f3wienie do firmy kurierskiej. Po poprawnym utworzeniu przesy\u0142ki zewn\u0119trzny system zwraca numer: Pole Warto\u015b\u0107 local_order_id 5021 shipment_id SHIP-778811 Ten numer musi zosta\u0107 zapisany natychmiast i atomowo. Je\u015bli zapis si\u0119 nie powiedzie, system mo\u017ce ponownie wys\u0142a\u0107 to samo zam\u00f3wienie i wygenerowa\u0107 kolejn\u0105 przesy\u0142k\u0119. Przyk\u0142ad w Python J\u0119zyk Kod Python python orders = {5021: None} external_id = &#8222;SHIP-778811&#8221; if orders[5021] is None: orders[5021] = external_id print(orders) Kod jest prosty, ale pokazuje podstawow\u0105 zasad\u0119: najpierw sprawdzenie istniej\u0105cego powi\u0105zania, potem zapis. Przyk\u0142ad w C++ J\u0119zyk Kod C++ cpp #include &lt;iostream&gt; #include &lt;map&gt; using namespace std; int main() { map&lt;int, string&gt; orders; orders[5021] = &#8222;&#8221;; if (orders[5021].empty()) { orders[5021] = &#8222;SHIP-778811&#8221;; } cout &lt;&lt; orders[5021] &lt;&lt; endl; return 0; } Przyk\u0142ad w C J\u0119zyk Kod C c #include &lt;stdio.h&gt; #include &lt;string.h&gt; int main() { int local_id = 5021; char external_id[20] = &#8222;&#8221;; if (strlen(external_id) == 0) { strcpy(external_id, &#8222;SHIP-778811&#8221;); } printf(&#8222;%d -&gt; %s\\n&#8221;, local_id, external_id); return 0; } Idempotencja jako zabezpieczenie praktyczne Je\u017celi ta sama operacja zostanie wykonana dwa razy, wynik powinien pozosta\u0107 taki sam. To bardzo wa\u017cne przy: Bez tego jedna awaria sieci mo\u017ce stworzy\u0107 realn\u0105 strat\u0119 finansow\u0105. Najcz\u0119\u015bciej stosuje si\u0119: Mapowanie identyfikator\u00f3w a wydajno\u015b\u0107 wyszukiwania zale\u017cy od struktury danych, indeks\u00f3w oraz sposobu aktualizacji rekord\u00f3w Przy ma\u0142ej skali wszystko dzia\u0142a szybko. Problem pojawia si\u0119 przy milionach rekord\u00f3w. Je\u015bli tabela translacji ma 20 milion\u00f3w wpis\u00f3w, a ka\u017cde zapytanie wykonuje pe\u0142ne skanowanie, op\u00f3\u017anienia rosn\u0105 gwa\u0142townie. Przybli\u017cone r\u00f3\u017cnice: Operacja Z\u0142o\u017cono\u015b\u0107 wyszukiwanie liniowe w li\u015bcie O(n) wyszukiwanie w drzewie zbalansowanym O(log n) tablica haszuj\u0105ca \u015brednio O(1) To nie jest teoria akademicka. Przy 10 rekordach r\u00f3\u017cnica jest niewidoczna. Przy 10 milionach oznacza sekundy albo milisekundy. Wz\u00f3r opisuj\u0105cy koszt wyszukiwania liniowego Zastosowanie Wz\u00f3r \u015brednia liczba por\u00f3wna\u0144 n \/ 2 f(n)=n2f(n)=\\frac{n}{2}f(n)=2n\u200b Dla miliona rekord\u00f3w \u015brednio potrzeba oko\u0142o 500 000 por\u00f3wna\u0144. To ju\u017c realny koszt procesora i czasu odpowiedzi. Wz\u00f3r przy wyszukiwaniu logarytmicznym Zastosowanie Wz\u00f3r liczba krok\u00f3w log2(n) f(n)=log\u20612(n)f(n)=\\log_2(n)f(n)=log2\u200b(n) Dla miliona rekord\u00f3w to oko\u0142o 20 krok\u00f3w zamiast setek tysi\u0119cy. Praktyczne zasady projektowe Brak punktu 7 jest cz\u0119sty. Gdy integracja si\u0119 psuje, zesp\u00f3\u0142 cz\u0119sto nie ma narz\u0119dzia do bezpiecznej korekty danych. Najcz\u0119stsze b\u0142\u0119dy praktyczne i miejsca, w kt\u00f3rych system zaczyna generowa\u0107 koszt zamiast porz\u0105dku Pierwszy b\u0142\u0105d to u\u017cywanie adresu e-mail jako jedynego klucza. U\u017cytkownik mo\u017ce go zmieni\u0107, mo\u017ce mie\u0107 kilka adres\u00f3w albo wsp\u00f3\u0142dzielony adres firmowy. Drugi b\u0142\u0105d to brak historii zmian. Je\u015bli identyfikator zewn\u0119trzny zostanie zmieniony przez partnera, system bez historii traci mo\u017cliwo\u015b\u0107 audytu. Trzeci b\u0142\u0105d to synchronizacja \u201ena skr\u00f3ty\u201d, czyli r\u0119czne dopisywanie warto\u015bci bez walidacji. To zwykle ko\u0144czy si\u0119 trudnym do odtworzenia stanem danych. Czwarty b\u0142\u0105d to brak transakcji. Je\u015bli zapis lokalny si\u0119 powiedzie, ale zapis relacji nie \u2014 system staje si\u0119 niesp\u00f3jny. Pi\u0105ty b\u0142\u0105d to nadmierne zaufanie do danych wej\u015bciowych. Integracja powinna zak\u0142ada\u0107, \u017ce dane zewn\u0119trzne bywaj\u0105 b\u0142\u0119dne. FAQ Czy UUID zawsze jest lepszy od zwyk\u0142ego INT? Nie zawsze. UUID daje wi\u0119ksz\u0105 unikalno\u015b\u0107 globaln\u0105 i dobrze dzia\u0142a w systemach rozproszonych, ale zajmuje wi\u0119cej miejsca i mo\u017ce pogarsza\u0107 wydajno\u015b\u0107 indeks\u00f3w. Dla prostych system\u00f3w lokalnych INT cz\u0119sto jest lepszy. Czy klucz biznesowy mo\u017ce by\u0107 kluczem g\u0142\u00f3wnym? Technicznie tak, ale zwykle nie warto. Je\u015bli numer klienta lub NIP si\u0119 zmieni, aktualizacja staje si\u0119 kosztowna i ryzykowna. Lepiej u\u017cywa\u0107 osobnego klucza technicznego. Czy tabela translacji jest potrzebna w ma\u0142ym systemie? Je\u015bli system ma tylko jedn\u0105 baz\u0119 i nie komunikuje si\u0119 z niczym zewn\u0119trznym, cz\u0119sto nie. Gdy pojawia si\u0119 API, ERP albo migracja danych &#8211; staje si\u0119 bardzo przydatna. Co zrobi\u0107 po wykryciu duplikat\u00f3w? Najpierw ustali\u0107 \u017ar\u00f3d\u0142o problemu, potem zablokowa\u0107 dalsze powstawanie b\u0142\u0119du. Dopiero p\u00f3\u017aniej scala\u0107 dane. R\u0119czne usuwanie rekord\u00f3w bez analizy zwykle pogarsza sytuacj\u0119. Czy warto logowa\u0107 ka\u017cde powi\u0105zanie? Tak, szczeg\u00f3lnie przy operacjach finansowych i magazynowych. Koszt miejsca jest zwykle ma\u0142y w por\u00f3wnaniu z czasem potrzebnym na analiz\u0119 awarii bez historii zdarze\u0144. Dobrze zaprojektowana warstwa translacji identyfikator\u00f3w nie jest dodatkiem technicznym, tylko elementem bezpiecze\u0144stwa danych. To ona decyduje, czy po kilku miesi\u0105cach system nadal da si\u0119 kontrolowa\u0107, czy zaczyna dzia\u0142a\u0107 wy\u0142\u0105cznie \u201ebo jeszcze si\u0119 nie zepsu\u0142\u201d. \u0179r\u00f3d\u0142o Foto: Freepik<\/p>\n","protected":false},"author":1,"featured_media":1362,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,1],"tags":[],"class_list":["post-1361","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kodowanie","category-poradnik"],"_links":{"self":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1361","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/comments?post=1361"}],"version-history":[{"count":1,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1361\/revisions"}],"predecessor-version":[{"id":1363,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1361\/revisions\/1363"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media\/1362"}],"wp:attachment":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media?parent=1361"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/categories?post=1361"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/tags?post=1361"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}