[{"data":1,"prerenderedAt":2009},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fru\u002Fdata\u002Fidentity-resolution-6-signalov-ednom-lichnosti":12},{"i18nKey":4,"paths":5},"data-003-2026-05",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11},"\u002Fde\u002Fdata\u002Fidentity-resolution-6-signale-zu-einer-kundenidentitaet","\u002Fen\u002Fdata\u002Fidentity-resolution-six-signals-to-unified-customer-identity","\u002Fes\u002Fdata\u002Fresolucion-de-identidad-de-6-senales-a-perfil-unico","\u002Ffr\u002Fdata\u002Fresolution-identite-6-signaux-vers-une-identite-client-unifiee","\u002Fit\u002Fdata\u002Frisoluzione-identita-6-segnali-a-profilo-unico","\u002Fru\u002Fdata\u002Fidentity-resolution-6-signalov-k-edinomu-identifikacionnomu-kodu-polzovatelya",{"_path":13,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":2003,"_id":2004,"_source":2005,"_file":2006,"_stem":2007,"_extension":2008},"\u002Fru\u002Fdata\u002Fidentity-resolution-6-signalov-ednom-lichnosti","data",false,"","Identity Resolution: 6 сигналов в одну идентичность клиента","Техническая архитектура объединения распределенных сигналов в единый профиль клиента через hash matching, вероятностное связывание и household identity.","2026-05-31",[21,22,23,24,25],"identity-resolution","cdp","first-party-data","probabilistic-matching","hash-matching",8,"Roibase",{"type":29,"children":30,"toc":1995},"root",[31,39,46,76,407,435,470,476,481,494,1030,1057,1077,1083,1096,1108,1272,1305,1320,1326,1355,1360,1646,1651,1657,1662,1667,1702,1708,1713,1989],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36],{"type":37,"value":38},"text","Пользователь регистрируется по email, совершает заказ из мобильного приложения, в другой день открывает заявку в поддержку с браузера. Cookie ID, device ID, хешированный email, IP, session ID, идентификатор пользователя — шесть разных сигналов. Без identity resolution они выглядят как шесть разных \"клиентов\". Атрибуция рекламы рассчитывается неправильно, модель LTV остается искаженной, теряются сигналы retention. Merge User ID в Google Analytics 4 объединяет только аутентифицированные сессии, не связывая анонимное поведение. CDP-системы продают probabilistic stitching, но не показывают структуру таблиц. Чтобы запустить identity graph в production, нужно объединить hash matching, вероятностное связывание и household identity.",{"type":32,"tag":40,"props":41,"children":43},"h2",{"id":42},"hash-matching-позвоночник-детерминированного-объединения",[44],{"type":37,"value":45},"Hash Matching: Позвоночник детерминированного объединения",{"type":32,"tag":33,"props":47,"children":48},{},[49,51,58,60,66,68,74],{"type":37,"value":50},"Hash matching устанавливает \"точную\" связь между двумя сигналами через сопоставление SHA-256 хешей одного email или номера телефона. Когда пользователь регистрируется на веб-сайте с ",{"type":32,"tag":52,"props":53,"children":55},"code",{"className":54},[],[56],{"type":37,"value":57},"user@example.com",{"type":37,"value":59},", хешируйте это значение в SHA-256 и напишите в таблицу ",{"type":32,"tag":52,"props":61,"children":63},{"className":62},[],[64],{"type":37,"value":65},"identity_signals",{"type":37,"value":67}," в BigQuery как колонку ",{"type":32,"tag":52,"props":69,"children":71},{"className":70},[],[72],{"type":37,"value":73},"hashed_email",{"type":37,"value":75},". При входе из мобильного приложения с тем же email хешированный email будет одинаковым в обоих местах — объедините две записи.",{"type":32,"tag":77,"props":78,"children":82},"pre",{"className":79,"code":80,"language":81,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","-- Пример детерминированного совпадения в BigQuery\nCREATE OR REPLACE TABLE `project.dataset.merged_identities` AS\nSELECT\n  web.anonymous_id AS web_cookie_id,\n  mobile.device_id AS mobile_device_id,\n  web.hashed_email,\n  MIN(web.first_seen_timestamp) AS first_seen\nFROM `project.dataset.web_events` web\nINNER JOIN `project.dataset.mobile_events` mobile\n  ON web.hashed_email = mobile.hashed_email\nWHERE web.hashed_email IS NOT NULL\nGROUP BY 1,2,3;\n","sql",[83],{"type":32,"tag":52,"props":84,"children":85},{"__ignoreMap":16},[86,98,134,143,174,201,222,265,283,302,343,369],{"type":32,"tag":87,"props":88,"children":91},"span",{"class":89,"line":90},"line",1,[92],{"type":32,"tag":87,"props":93,"children":95},{"style":94},"--shiki-default:#6A737D",[96],{"type":37,"value":97},"-- Пример детерминированного совпадения в BigQuery\n",{"type":32,"tag":87,"props":99,"children":101},{"class":89,"line":100},2,[102,108,113,118,123,129],{"type":32,"tag":87,"props":103,"children":105},{"style":104},"--shiki-default:#F97583",[106],{"type":37,"value":107},"CREATE",{"type":32,"tag":87,"props":109,"children":110},{"style":104},[111],{"type":37,"value":112}," OR",{"type":32,"tag":87,"props":114,"children":115},{"style":104},[116],{"type":37,"value":117}," REPLACE",{"type":32,"tag":87,"props":119,"children":120},{"style":104},[121],{"type":37,"value":122}," TABLE",{"type":32,"tag":87,"props":124,"children":126},{"style":125},"--shiki-default:#9ECBFF",[127],{"type":37,"value":128}," `project.dataset.merged_identities`",{"type":32,"tag":87,"props":130,"children":131},{"style":104},[132],{"type":37,"value":133}," AS\n",{"type":32,"tag":87,"props":135,"children":137},{"class":89,"line":136},3,[138],{"type":32,"tag":87,"props":139,"children":140},{"style":104},[141],{"type":37,"value":142},"SELECT\n",{"type":32,"tag":87,"props":144,"children":146},{"class":89,"line":145},4,[147,153,159,164,169],{"type":32,"tag":87,"props":148,"children":150},{"style":149},"--shiki-default:#79B8FF",[151],{"type":37,"value":152},"  web",{"type":32,"tag":87,"props":154,"children":156},{"style":155},"--shiki-default:#E1E4E8",[157],{"type":37,"value":158},".",{"type":32,"tag":87,"props":160,"children":161},{"style":149},[162],{"type":37,"value":163},"anonymous_id",{"type":32,"tag":87,"props":165,"children":166},{"style":104},[167],{"type":37,"value":168}," AS",{"type":32,"tag":87,"props":170,"children":171},{"style":155},[172],{"type":37,"value":173}," web_cookie_id,\n",{"type":32,"tag":87,"props":175,"children":177},{"class":89,"line":176},5,[178,183,187,192,196],{"type":32,"tag":87,"props":179,"children":180},{"style":149},[181],{"type":37,"value":182},"  mobile",{"type":32,"tag":87,"props":184,"children":185},{"style":155},[186],{"type":37,"value":158},{"type":32,"tag":87,"props":188,"children":189},{"style":149},[190],{"type":37,"value":191},"device_id",{"type":32,"tag":87,"props":193,"children":194},{"style":104},[195],{"type":37,"value":168},{"type":32,"tag":87,"props":197,"children":198},{"style":155},[199],{"type":37,"value":200}," mobile_device_id,\n",{"type":32,"tag":87,"props":202,"children":204},{"class":89,"line":203},6,[205,209,213,217],{"type":32,"tag":87,"props":206,"children":207},{"style":149},[208],{"type":37,"value":152},{"type":32,"tag":87,"props":210,"children":211},{"style":155},[212],{"type":37,"value":158},{"type":32,"tag":87,"props":214,"children":215},{"style":149},[216],{"type":37,"value":73},{"type":32,"tag":87,"props":218,"children":219},{"style":155},[220],{"type":37,"value":221},",\n",{"type":32,"tag":87,"props":223,"children":225},{"class":89,"line":224},7,[226,231,236,241,245,250,255,260],{"type":32,"tag":87,"props":227,"children":228},{"style":149},[229],{"type":37,"value":230},"  MIN",{"type":32,"tag":87,"props":232,"children":233},{"style":155},[234],{"type":37,"value":235},"(",{"type":32,"tag":87,"props":237,"children":238},{"style":149},[239],{"type":37,"value":240},"web",{"type":32,"tag":87,"props":242,"children":243},{"style":155},[244],{"type":37,"value":158},{"type":32,"tag":87,"props":246,"children":247},{"style":149},[248],{"type":37,"value":249},"first_seen_timestamp",{"type":32,"tag":87,"props":251,"children":252},{"style":155},[253],{"type":37,"value":254},") ",{"type":32,"tag":87,"props":256,"children":257},{"style":104},[258],{"type":37,"value":259},"AS",{"type":32,"tag":87,"props":261,"children":262},{"style":155},[263],{"type":37,"value":264}," first_seen\n",{"type":32,"tag":87,"props":266,"children":267},{"class":89,"line":26},[268,273,278],{"type":32,"tag":87,"props":269,"children":270},{"style":104},[271],{"type":37,"value":272},"FROM",{"type":32,"tag":87,"props":274,"children":275},{"style":125},[276],{"type":37,"value":277}," `project.dataset.web_events`",{"type":32,"tag":87,"props":279,"children":280},{"style":155},[281],{"type":37,"value":282}," web\n",{"type":32,"tag":87,"props":284,"children":286},{"class":89,"line":285},9,[287,292,297],{"type":32,"tag":87,"props":288,"children":289},{"style":104},[290],{"type":37,"value":291},"INNER JOIN",{"type":32,"tag":87,"props":293,"children":294},{"style":125},[295],{"type":37,"value":296}," `project.dataset.mobile_events`",{"type":32,"tag":87,"props":298,"children":299},{"style":155},[300],{"type":37,"value":301}," mobile\n",{"type":32,"tag":87,"props":303,"children":305},{"class":89,"line":304},10,[306,311,316,320,324,329,334,338],{"type":32,"tag":87,"props":307,"children":308},{"style":104},[309],{"type":37,"value":310},"  ON",{"type":32,"tag":87,"props":312,"children":313},{"style":149},[314],{"type":37,"value":315}," web",{"type":32,"tag":87,"props":317,"children":318},{"style":155},[319],{"type":37,"value":158},{"type":32,"tag":87,"props":321,"children":322},{"style":149},[323],{"type":37,"value":73},{"type":32,"tag":87,"props":325,"children":326},{"style":104},[327],{"type":37,"value":328}," =",{"type":32,"tag":87,"props":330,"children":331},{"style":149},[332],{"type":37,"value":333}," mobile",{"type":32,"tag":87,"props":335,"children":336},{"style":155},[337],{"type":37,"value":158},{"type":32,"tag":87,"props":339,"children":340},{"style":149},[341],{"type":37,"value":342},"hashed_email\n",{"type":32,"tag":87,"props":344,"children":346},{"class":89,"line":345},11,[347,352,356,360,364],{"type":32,"tag":87,"props":348,"children":349},{"style":104},[350],{"type":37,"value":351},"WHERE",{"type":32,"tag":87,"props":353,"children":354},{"style":149},[355],{"type":37,"value":315},{"type":32,"tag":87,"props":357,"children":358},{"style":155},[359],{"type":37,"value":158},{"type":32,"tag":87,"props":361,"children":362},{"style":149},[363],{"type":37,"value":73},{"type":32,"tag":87,"props":365,"children":366},{"style":104},[367],{"type":37,"value":368}," IS NOT NULL\n",{"type":32,"tag":87,"props":370,"children":372},{"class":89,"line":371},12,[373,378,383,388,393,397,402],{"type":32,"tag":87,"props":374,"children":375},{"style":104},[376],{"type":37,"value":377},"GROUP BY",{"type":32,"tag":87,"props":379,"children":380},{"style":149},[381],{"type":37,"value":382}," 1",{"type":32,"tag":87,"props":384,"children":385},{"style":155},[386],{"type":37,"value":387},",",{"type":32,"tag":87,"props":389,"children":390},{"style":149},[391],{"type":37,"value":392},"2",{"type":32,"tag":87,"props":394,"children":395},{"style":155},[396],{"type":37,"value":387},{"type":32,"tag":87,"props":398,"children":399},{"style":149},[400],{"type":37,"value":401},"3",{"type":32,"tag":87,"props":403,"children":404},{"style":155},[405],{"type":37,"value":406},";\n",{"type":32,"tag":33,"props":408,"children":409},{},[410,412,417,419,425,427,433],{"type":37,"value":411},"Этот запрос объединяет веб-cookie ID с мобильным device ID через хешированный email. ",{"type":32,"tag":52,"props":413,"children":415},{"className":414},[],[416],{"type":37,"value":291},{"type":37,"value":418}," детерминирован — приходят только точные совпадения. Чтобы собрать совпадающие сигналы под одним ",{"type":32,"tag":52,"props":420,"children":422},{"className":421},[],[423],{"type":37,"value":424},"canonical_user_id",{"type":37,"value":426},", используйте ",{"type":32,"tag":52,"props":428,"children":430},{"className":429},[],[431],{"type":37,"value":432},"ROW_NUMBER()",{"type":37,"value":434}," или генерирование UUID. Ограничение hash matching: если пользователь изменит email (старая учетная запись + новая учетная запись), они остаются двумя отдельными идентичностями. Здесь в дело вступает probabilistic layer.",{"type":32,"tag":33,"props":436,"children":437},{},[438,440,445,447,453,454,460,462,468],{"type":37,"value":439},"Hash matching совместим с GDPR и KVKK, потому что вы не храните простой текст email — хеш односторонний и необратимый. Однако он уязвим для атак по радужным таблицам, поэтому добавьте к хешам email вторичный сигнал вроде отпечатка устройства или диапазона IP. Одной колонки хеша недостаточно — храните ",{"type":32,"tag":52,"props":441,"children":443},{"className":442},[],[444],{"type":37,"value":73},{"type":37,"value":446},", ",{"type":32,"tag":52,"props":448,"children":450},{"className":449},[],[451],{"type":37,"value":452},"hashed_phone",{"type":37,"value":446},{"type":32,"tag":52,"props":455,"children":457},{"className":456},[],[458],{"type":37,"value":459},"hashed_customer_id",{"type":37,"value":461}," в отдельных колонках. Установите partitioning таблицы на ",{"type":32,"tag":52,"props":463,"children":465},{"className":464},[],[466],{"type":37,"value":467},"DATE(timestamp)",{"type":37,"value":469}," — identity resolution обычно инкрементальна, полная сканирование всей истории дорого.",{"type":32,"tag":40,"props":471,"children":473},{"id":472},"probabilistic-linking-управление-неопределенностью-через-скоры",[474],{"type":37,"value":475},"Probabilistic Linking: Управление неопределенностью через скоры",{"type":32,"tag":33,"props":477,"children":478},{},[479],{"type":37,"value":480},"Когда пользователь просматривает контент без регистрации, хешированный email отсутствует — есть только cookie ID, IP, user agent, timestamp сессии. Probabilistic matching взвешивает эти сигналы и выдает скор \"вероятность того же человека\". Если скор выше порога (например, 0.85), объедините две записи; если ниже — оставьте отдельно. Вендоры вроде LiveRamp, Merkle, Neustar продают такие скоры, но вы можете построить собственную модель на основе правил в собственном data warehouse.",{"type":32,"tag":33,"props":482,"children":483},{},[484,486,492],{"type":37,"value":485},"Пример логики: одинаковый IP + одинаковый отпечаток браузера (canvas hash) + сеанс в течение 5 минут → скор совпадения 90%. Одинаковый IP + разный браузер + разница 2 часа → скор 40%. При пороге 0.7 первая пара объединяется, вторая — нет. В BigQuery можете смоделировать это блоками ",{"type":32,"tag":52,"props":487,"children":489},{"className":488},[],[490],{"type":37,"value":491},"CASE WHEN",{"type":37,"value":493},":",{"type":32,"tag":77,"props":495,"children":497},{"className":79,"code":496,"language":81,"meta":16,"style":16},"SELECT\n  a.session_id AS session_a,\n  b.session_id AS session_b,\n  CASE\n    WHEN a.ip_address = b.ip_address\n      AND a.canvas_hash = b.canvas_hash\n      AND TIMESTAMP_DIFF(b.timestamp, a.timestamp, MINUTE) \u003C= 5\n    THEN 0.90\n    WHEN a.ip_address = b.ip_address\n      AND TIMESTAMP_DIFF(b.timestamp, a.timestamp, HOUR) \u003C= 2\n    THEN 0.40\n    ELSE 0.0\n  END AS match_score\nFROM `project.dataset.anonymous_sessions` a\nCROSS JOIN `project.dataset.anonymous_sessions` b\nWHERE a.session_id \u003C b.session_id\n  AND a.ip_address = b.ip_address\nQUALIFY match_score >= 0.70;\n",[498],{"type":32,"tag":52,"props":499,"children":500},{"__ignoreMap":16},[501,508,534,559,567,607,645,711,733,768,829,849,870,888,906,924,962,999],{"type":32,"tag":87,"props":502,"children":503},{"class":89,"line":90},[504],{"type":32,"tag":87,"props":505,"children":506},{"style":104},[507],{"type":37,"value":142},{"type":32,"tag":87,"props":509,"children":510},{"class":89,"line":100},[511,516,520,525,529],{"type":32,"tag":87,"props":512,"children":513},{"style":149},[514],{"type":37,"value":515},"  a",{"type":32,"tag":87,"props":517,"children":518},{"style":155},[519],{"type":37,"value":158},{"type":32,"tag":87,"props":521,"children":522},{"style":149},[523],{"type":37,"value":524},"session_id",{"type":32,"tag":87,"props":526,"children":527},{"style":104},[528],{"type":37,"value":168},{"type":32,"tag":87,"props":530,"children":531},{"style":155},[532],{"type":37,"value":533}," session_a,\n",{"type":32,"tag":87,"props":535,"children":536},{"class":89,"line":136},[537,542,546,550,554],{"type":32,"tag":87,"props":538,"children":539},{"style":149},[540],{"type":37,"value":541},"  b",{"type":32,"tag":87,"props":543,"children":544},{"style":155},[545],{"type":37,"value":158},{"type":32,"tag":87,"props":547,"children":548},{"style":149},[549],{"type":37,"value":524},{"type":32,"tag":87,"props":551,"children":552},{"style":104},[553],{"type":37,"value":168},{"type":32,"tag":87,"props":555,"children":556},{"style":155},[557],{"type":37,"value":558}," session_b,\n",{"type":32,"tag":87,"props":560,"children":561},{"class":89,"line":145},[562],{"type":32,"tag":87,"props":563,"children":564},{"style":104},[565],{"type":37,"value":566},"  CASE\n",{"type":32,"tag":87,"props":568,"children":569},{"class":89,"line":176},[570,575,580,584,589,593,598,602],{"type":32,"tag":87,"props":571,"children":572},{"style":104},[573],{"type":37,"value":574},"    WHEN",{"type":32,"tag":87,"props":576,"children":577},{"style":149},[578],{"type":37,"value":579}," a",{"type":32,"tag":87,"props":581,"children":582},{"style":155},[583],{"type":37,"value":158},{"type":32,"tag":87,"props":585,"children":586},{"style":149},[587],{"type":37,"value":588},"ip_address",{"type":32,"tag":87,"props":590,"children":591},{"style":104},[592],{"type":37,"value":328},{"type":32,"tag":87,"props":594,"children":595},{"style":149},[596],{"type":37,"value":597}," b",{"type":32,"tag":87,"props":599,"children":600},{"style":155},[601],{"type":37,"value":158},{"type":32,"tag":87,"props":603,"children":604},{"style":149},[605],{"type":37,"value":606},"ip_address\n",{"type":32,"tag":87,"props":608,"children":609},{"class":89,"line":203},[610,615,619,623,628,632,636,640],{"type":32,"tag":87,"props":611,"children":612},{"style":104},[613],{"type":37,"value":614},"      AND",{"type":32,"tag":87,"props":616,"children":617},{"style":149},[618],{"type":37,"value":579},{"type":32,"tag":87,"props":620,"children":621},{"style":155},[622],{"type":37,"value":158},{"type":32,"tag":87,"props":624,"children":625},{"style":149},[626],{"type":37,"value":627},"canvas_hash",{"type":32,"tag":87,"props":629,"children":630},{"style":104},[631],{"type":37,"value":328},{"type":32,"tag":87,"props":633,"children":634},{"style":149},[635],{"type":37,"value":597},{"type":32,"tag":87,"props":637,"children":638},{"style":155},[639],{"type":37,"value":158},{"type":32,"tag":87,"props":641,"children":642},{"style":149},[643],{"type":37,"value":644},"canvas_hash\n",{"type":32,"tag":87,"props":646,"children":647},{"class":89,"line":224},[648,652,657,662,666,671,675,680,684,688,692,697,701,706],{"type":32,"tag":87,"props":649,"children":650},{"style":104},[651],{"type":37,"value":614},{"type":32,"tag":87,"props":653,"children":654},{"style":155},[655],{"type":37,"value":656}," TIMESTAMP_DIFF(",{"type":32,"tag":87,"props":658,"children":659},{"style":149},[660],{"type":37,"value":661},"b",{"type":32,"tag":87,"props":663,"children":664},{"style":155},[665],{"type":37,"value":158},{"type":32,"tag":87,"props":667,"children":668},{"style":149},[669],{"type":37,"value":670},"timestamp",{"type":32,"tag":87,"props":672,"children":673},{"style":155},[674],{"type":37,"value":446},{"type":32,"tag":87,"props":676,"children":677},{"style":149},[678],{"type":37,"value":679},"a",{"type":32,"tag":87,"props":681,"children":682},{"style":155},[683],{"type":37,"value":158},{"type":32,"tag":87,"props":685,"children":686},{"style":149},[687],{"type":37,"value":670},{"type":32,"tag":87,"props":689,"children":690},{"style":155},[691],{"type":37,"value":446},{"type":32,"tag":87,"props":693,"children":694},{"style":104},[695],{"type":37,"value":696},"MINUTE",{"type":32,"tag":87,"props":698,"children":699},{"style":155},[700],{"type":37,"value":254},{"type":32,"tag":87,"props":702,"children":703},{"style":104},[704],{"type":37,"value":705},"\u003C=",{"type":32,"tag":87,"props":707,"children":708},{"style":149},[709],{"type":37,"value":710}," 5\n",{"type":32,"tag":87,"props":712,"children":713},{"class":89,"line":26},[714,719,724,728],{"type":32,"tag":87,"props":715,"children":716},{"style":104},[717],{"type":37,"value":718},"    THEN",{"type":32,"tag":87,"props":720,"children":721},{"style":149},[722],{"type":37,"value":723}," 0",{"type":32,"tag":87,"props":725,"children":726},{"style":155},[727],{"type":37,"value":158},{"type":32,"tag":87,"props":729,"children":730},{"style":149},[731],{"type":37,"value":732},"90\n",{"type":32,"tag":87,"props":734,"children":735},{"class":89,"line":285},[736,740,744,748,752,756,760,764],{"type":32,"tag":87,"props":737,"children":738},{"style":104},[739],{"type":37,"value":574},{"type":32,"tag":87,"props":741,"children":742},{"style":149},[743],{"type":37,"value":579},{"type":32,"tag":87,"props":745,"children":746},{"style":155},[747],{"type":37,"value":158},{"type":32,"tag":87,"props":749,"children":750},{"style":149},[751],{"type":37,"value":588},{"type":32,"tag":87,"props":753,"children":754},{"style":104},[755],{"type":37,"value":328},{"type":32,"tag":87,"props":757,"children":758},{"style":149},[759],{"type":37,"value":597},{"type":32,"tag":87,"props":761,"children":762},{"style":155},[763],{"type":37,"value":158},{"type":32,"tag":87,"props":765,"children":766},{"style":149},[767],{"type":37,"value":606},{"type":32,"tag":87,"props":769,"children":770},{"class":89,"line":304},[771,775,779,783,787,791,795,799,803,807,811,816,820,824],{"type":32,"tag":87,"props":772,"children":773},{"style":104},[774],{"type":37,"value":614},{"type":32,"tag":87,"props":776,"children":777},{"style":155},[778],{"type":37,"value":656},{"type":32,"tag":87,"props":780,"children":781},{"style":149},[782],{"type":37,"value":661},{"type":32,"tag":87,"props":784,"children":785},{"style":155},[786],{"type":37,"value":158},{"type":32,"tag":87,"props":788,"children":789},{"style":149},[790],{"type":37,"value":670},{"type":32,"tag":87,"props":792,"children":793},{"style":155},[794],{"type":37,"value":446},{"type":32,"tag":87,"props":796,"children":797},{"style":149},[798],{"type":37,"value":679},{"type":32,"tag":87,"props":800,"children":801},{"style":155},[802],{"type":37,"value":158},{"type":32,"tag":87,"props":804,"children":805},{"style":149},[806],{"type":37,"value":670},{"type":32,"tag":87,"props":808,"children":809},{"style":155},[810],{"type":37,"value":446},{"type":32,"tag":87,"props":812,"children":813},{"style":104},[814],{"type":37,"value":815},"HOUR",{"type":32,"tag":87,"props":817,"children":818},{"style":155},[819],{"type":37,"value":254},{"type":32,"tag":87,"props":821,"children":822},{"style":104},[823],{"type":37,"value":705},{"type":32,"tag":87,"props":825,"children":826},{"style":149},[827],{"type":37,"value":828}," 2\n",{"type":32,"tag":87,"props":830,"children":831},{"class":89,"line":345},[832,836,840,844],{"type":32,"tag":87,"props":833,"children":834},{"style":104},[835],{"type":37,"value":718},{"type":32,"tag":87,"props":837,"children":838},{"style":149},[839],{"type":37,"value":723},{"type":32,"tag":87,"props":841,"children":842},{"style":155},[843],{"type":37,"value":158},{"type":32,"tag":87,"props":845,"children":846},{"style":149},[847],{"type":37,"value":848},"40\n",{"type":32,"tag":87,"props":850,"children":851},{"class":89,"line":371},[852,857,861,865],{"type":32,"tag":87,"props":853,"children":854},{"style":104},[855],{"type":37,"value":856},"    ELSE",{"type":32,"tag":87,"props":858,"children":859},{"style":149},[860],{"type":37,"value":723},{"type":32,"tag":87,"props":862,"children":863},{"style":155},[864],{"type":37,"value":158},{"type":32,"tag":87,"props":866,"children":867},{"style":149},[868],{"type":37,"value":869},"0\n",{"type":32,"tag":87,"props":871,"children":873},{"class":89,"line":872},13,[874,879,883],{"type":32,"tag":87,"props":875,"children":876},{"style":104},[877],{"type":37,"value":878},"  END",{"type":32,"tag":87,"props":880,"children":881},{"style":104},[882],{"type":37,"value":168},{"type":32,"tag":87,"props":884,"children":885},{"style":155},[886],{"type":37,"value":887}," match_score\n",{"type":32,"tag":87,"props":889,"children":891},{"class":89,"line":890},14,[892,896,901],{"type":32,"tag":87,"props":893,"children":894},{"style":104},[895],{"type":37,"value":272},{"type":32,"tag":87,"props":897,"children":898},{"style":125},[899],{"type":37,"value":900}," `project.dataset.anonymous_sessions`",{"type":32,"tag":87,"props":902,"children":903},{"style":155},[904],{"type":37,"value":905}," a\n",{"type":32,"tag":87,"props":907,"children":909},{"class":89,"line":908},15,[910,915,919],{"type":32,"tag":87,"props":911,"children":912},{"style":104},[913],{"type":37,"value":914},"CROSS JOIN",{"type":32,"tag":87,"props":916,"children":917},{"style":125},[918],{"type":37,"value":900},{"type":32,"tag":87,"props":920,"children":921},{"style":155},[922],{"type":37,"value":923}," b\n",{"type":32,"tag":87,"props":925,"children":927},{"class":89,"line":926},16,[928,932,936,940,944,949,953,957],{"type":32,"tag":87,"props":929,"children":930},{"style":104},[931],{"type":37,"value":351},{"type":32,"tag":87,"props":933,"children":934},{"style":149},[935],{"type":37,"value":579},{"type":32,"tag":87,"props":937,"children":938},{"style":155},[939],{"type":37,"value":158},{"type":32,"tag":87,"props":941,"children":942},{"style":149},[943],{"type":37,"value":524},{"type":32,"tag":87,"props":945,"children":946},{"style":104},[947],{"type":37,"value":948}," \u003C",{"type":32,"tag":87,"props":950,"children":951},{"style":149},[952],{"type":37,"value":597},{"type":32,"tag":87,"props":954,"children":955},{"style":155},[956],{"type":37,"value":158},{"type":32,"tag":87,"props":958,"children":959},{"style":149},[960],{"type":37,"value":961},"session_id\n",{"type":32,"tag":87,"props":963,"children":965},{"class":89,"line":964},17,[966,971,975,979,983,987,991,995],{"type":32,"tag":87,"props":967,"children":968},{"style":104},[969],{"type":37,"value":970},"  AND",{"type":32,"tag":87,"props":972,"children":973},{"style":149},[974],{"type":37,"value":579},{"type":32,"tag":87,"props":976,"children":977},{"style":155},[978],{"type":37,"value":158},{"type":32,"tag":87,"props":980,"children":981},{"style":149},[982],{"type":37,"value":588},{"type":32,"tag":87,"props":984,"children":985},{"style":104},[986],{"type":37,"value":328},{"type":32,"tag":87,"props":988,"children":989},{"style":149},[990],{"type":37,"value":597},{"type":32,"tag":87,"props":992,"children":993},{"style":155},[994],{"type":37,"value":158},{"type":32,"tag":87,"props":996,"children":997},{"style":149},[998],{"type":37,"value":606},{"type":32,"tag":87,"props":1000,"children":1002},{"class":89,"line":1001},18,[1003,1008,1013,1017,1021,1026],{"type":32,"tag":87,"props":1004,"children":1005},{"style":155},[1006],{"type":37,"value":1007},"QUALIFY match_score ",{"type":32,"tag":87,"props":1009,"children":1010},{"style":104},[1011],{"type":37,"value":1012},">=",{"type":32,"tag":87,"props":1014,"children":1015},{"style":149},[1016],{"type":37,"value":723},{"type":32,"tag":87,"props":1018,"children":1019},{"style":155},[1020],{"type":37,"value":158},{"type":32,"tag":87,"props":1022,"children":1023},{"style":149},[1024],{"type":37,"value":1025},"70",{"type":32,"tag":87,"props":1027,"children":1028},{"style":155},[1029],{"type":37,"value":406},{"type":32,"tag":33,"props":1031,"children":1032},{},[1033,1035,1040,1042,1048,1050,1055],{"type":37,"value":1034},"Этот запрос делает ",{"type":32,"tag":52,"props":1036,"children":1038},{"className":1037},[],[1039],{"type":37,"value":914},{"type":37,"value":1041}," — на миллионах строк стоимость взлетит. В production нужны window function или bucketing: разделите диапазон IP по префиксу (например, ",{"type":32,"tag":52,"props":1043,"children":1045},{"className":1044},[],[1046],{"type":37,"value":1047},"\u002F24",{"type":37,"value":1049}," CIDR), сравните только последние 100 сессий через ",{"type":32,"tag":52,"props":1051,"children":1053},{"className":1052},[],[1054],{"type":37,"value":432},{"type":37,"value":1056},". Риск probabilistic matching — false positive: два разных пользователя с одного IP (корпоративный Wi-Fi, общее VPN) в один момент времени могут неправильно объединиться. Поэтому держите порог скора 0.85–0.90 и подтверждайте через cross-device сигналы.",{"type":32,"tag":33,"props":1058,"children":1059},{},[1060,1062,1068,1070,1075],{"type":37,"value":1061},"Более сложная модель с машинным обучением: логистическая регрессия или gradient boosting для бинарной классификации \"один пользователь\". Набор признаков: расстояние Хэмминга IP, сходство user agent по Левенштейну, смещение временных зон, счетчик сеансов. Размеченные данные обучения — положительные примеры из известных пар ",{"type":32,"tag":52,"props":1063,"children":1065},{"className":1064},[],[1066],{"type":37,"value":1067},"user_id",{"type":37,"value":1069},", отрицательные — из разных ",{"type":32,"tag":52,"props":1071,"children":1073},{"className":1072},[],[1074],{"type":37,"value":1067},{"type":37,"value":1076},". Модель выдает скор от 0 до 1, порог остается ручная настройка. Для этого подхода нужен pipeline Vertex AI или Sagemaker — инженерия данных + machine learning работают вместе.",{"type":32,"tag":40,"props":1078,"children":1080},{"id":1079},"household-identity-один-дом-разные-пользователи",[1081],{"type":37,"value":1082},"Household Identity: один дом, разные пользователи",{"type":32,"tag":33,"props":1084,"children":1085},{},[1086,1088,1094],{"type":37,"value":1087},"Слой \"household\" в identity resolution: группировка разных пользователей с одного IP или физического адреса в \"семейную единицу\" для маркетинг-таргетинга. Например, на сайте электроники мама смотрит детскую одежду, отец покупает электронику — два разных user ID, но один адрес доставки. Household graph объединяет их под ",{"type":32,"tag":52,"props":1089,"children":1091},{"className":1090},[],[1092],{"type":37,"value":1093},"household_id",{"type":37,"value":1095},". На рекламных платформах (Facebook Ads, Google Ads) это продается как household targeting, но вам нужно смоделировать это в first-party data.",{"type":32,"tag":33,"props":1097,"children":1098},{},[1099,1101,1107],{"type":37,"value":1100},"Нормализуйте адрес доставки в BigQuery: удалите различия в регистре, пробелах, номерах квартир. Потом захешируйте и используйте как ",{"type":32,"tag":52,"props":1102,"children":1104},{"className":1103},[],[1105],{"type":37,"value":1106},"household_key",{"type":37,"value":493},{"type":32,"tag":77,"props":1109,"children":1111},{"className":79,"code":1110,"language":81,"meta":16,"style":16},"CREATE OR REPLACE TABLE `project.dataset.household_mapping` AS\nSELECT\n  user_id,\n  TO_HEX(SHA256(\n    LOWER(REGEXP_REPLACE(CONCAT(street, city, postal_code), r'\\s+', ''))\n  )) AS household_key\nFROM `project.dataset.user_addresses`\nWHERE street IS NOT NULL AND postal_code IS NOT NULL;\n",[1112],{"type":32,"tag":52,"props":1113,"children":1114},{"__ignoreMap":16},[1115,1143,1150,1158,1166,1208,1225,1237],{"type":32,"tag":87,"props":1116,"children":1117},{"class":89,"line":90},[1118,1122,1126,1130,1134,1139],{"type":32,"tag":87,"props":1119,"children":1120},{"style":104},[1121],{"type":37,"value":107},{"type":32,"tag":87,"props":1123,"children":1124},{"style":104},[1125],{"type":37,"value":112},{"type":32,"tag":87,"props":1127,"children":1128},{"style":104},[1129],{"type":37,"value":117},{"type":32,"tag":87,"props":1131,"children":1132},{"style":104},[1133],{"type":37,"value":122},{"type":32,"tag":87,"props":1135,"children":1136},{"style":125},[1137],{"type":37,"value":1138}," `project.dataset.household_mapping`",{"type":32,"tag":87,"props":1140,"children":1141},{"style":104},[1142],{"type":37,"value":133},{"type":32,"tag":87,"props":1144,"children":1145},{"class":89,"line":100},[1146],{"type":32,"tag":87,"props":1147,"children":1148},{"style":104},[1149],{"type":37,"value":142},{"type":32,"tag":87,"props":1151,"children":1152},{"class":89,"line":136},[1153],{"type":32,"tag":87,"props":1154,"children":1155},{"style":155},[1156],{"type":37,"value":1157},"  user_id,\n",{"type":32,"tag":87,"props":1159,"children":1160},{"class":89,"line":145},[1161],{"type":32,"tag":87,"props":1162,"children":1163},{"style":155},[1164],{"type":37,"value":1165},"  TO_HEX(SHA256(\n",{"type":32,"tag":87,"props":1167,"children":1168},{"class":89,"line":176},[1169,1174,1179,1184,1189,1194,1198,1203],{"type":32,"tag":87,"props":1170,"children":1171},{"style":149},[1172],{"type":37,"value":1173},"    LOWER",{"type":32,"tag":87,"props":1175,"children":1176},{"style":155},[1177],{"type":37,"value":1178},"(REGEXP_REPLACE(",{"type":32,"tag":87,"props":1180,"children":1181},{"style":149},[1182],{"type":37,"value":1183},"CONCAT",{"type":32,"tag":87,"props":1185,"children":1186},{"style":155},[1187],{"type":37,"value":1188},"(street, city, postal_code), r",{"type":32,"tag":87,"props":1190,"children":1191},{"style":125},[1192],{"type":37,"value":1193},"'\\s+'",{"type":32,"tag":87,"props":1195,"children":1196},{"style":155},[1197],{"type":37,"value":446},{"type":32,"tag":87,"props":1199,"children":1200},{"style":125},[1201],{"type":37,"value":1202},"''",{"type":32,"tag":87,"props":1204,"children":1205},{"style":155},[1206],{"type":37,"value":1207},"))\n",{"type":32,"tag":87,"props":1209,"children":1210},{"class":89,"line":203},[1211,1216,1220],{"type":32,"tag":87,"props":1212,"children":1213},{"style":155},[1214],{"type":37,"value":1215},"  )) ",{"type":32,"tag":87,"props":1217,"children":1218},{"style":104},[1219],{"type":37,"value":259},{"type":32,"tag":87,"props":1221,"children":1222},{"style":155},[1223],{"type":37,"value":1224}," household_key\n",{"type":32,"tag":87,"props":1226,"children":1227},{"class":89,"line":224},[1228,1232],{"type":32,"tag":87,"props":1229,"children":1230},{"style":104},[1231],{"type":37,"value":272},{"type":32,"tag":87,"props":1233,"children":1234},{"style":125},[1235],{"type":37,"value":1236}," `project.dataset.user_addresses`\n",{"type":32,"tag":87,"props":1238,"children":1239},{"class":89,"line":26},[1240,1244,1249,1254,1259,1264,1268],{"type":32,"tag":87,"props":1241,"children":1242},{"style":104},[1243],{"type":37,"value":351},{"type":32,"tag":87,"props":1245,"children":1246},{"style":155},[1247],{"type":37,"value":1248}," street ",{"type":32,"tag":87,"props":1250,"children":1251},{"style":104},[1252],{"type":37,"value":1253},"IS NOT NULL",{"type":32,"tag":87,"props":1255,"children":1256},{"style":104},[1257],{"type":37,"value":1258}," AND",{"type":32,"tag":87,"props":1260,"children":1261},{"style":155},[1262],{"type":37,"value":1263}," postal_code ",{"type":32,"tag":87,"props":1265,"children":1266},{"style":104},[1267],{"type":37,"value":1253},{"type":32,"tag":87,"props":1269,"children":1270},{"style":155},[1271],{"type":37,"value":406},{"type":32,"tag":33,"props":1273,"children":1274},{},[1275,1277,1282,1284,1289,1291,1296,1298,1303],{"type":37,"value":1276},"Эта таблица дает маппинг ",{"type":32,"tag":52,"props":1278,"children":1280},{"className":1279},[],[1281],{"type":37,"value":1067},{"type":37,"value":1283}," → ",{"type":32,"tag":52,"props":1285,"children":1287},{"className":1286},[],[1288],{"type":37,"value":1106},{"type":37,"value":1290},". Сгруппируйте пользователей под одним ",{"type":32,"tag":52,"props":1292,"children":1294},{"className":1293},[],[1295],{"type":37,"value":1106},{"type":37,"value":1297}," и присвойте им ",{"type":32,"tag":52,"props":1299,"children":1301},{"className":1300},[],[1302],{"type":37,"value":1093},{"type":37,"value":1304},". Household identity отличается от cross-device identity — не устройства одного человека, а люди одного дома. Риск приватности высок: объединение двух разных взрослых пользователей в один household может нарушить принцип минимизации данных (KVKK ст. 5). Поэтому используйте household graph только для агрегированной аналитики и анонимного таргетинга, не для объединения персональных профилей.",{"type":32,"tag":33,"props":1306,"children":1307},{},[1308,1310,1318],{"type":37,"value":1309},"Добавьте ко второму слою сигналы: хеш SSID Wi-Fi (если мобильное приложение даст разрешение), Bluetooth beacon (физический магазин), shared payment method (одна кредитная карта). Эти сигналы содержат PII и требуют хеширования + encrypted storage. CDP-системы (Segment, mParticle, RudderStack) предлагают household resolution как \"relationship graph\", но если построить собственную модель в BigQuery, получаете больше контроля — видите, как каждый сигнал взвешивается. В работе Roibase ",{"type":32,"tag":679,"props":1311,"children":1315},{"href":1312,"rel":1313},"https:\u002F\u002Fwww.roibase.com.tr\u002Fru\u002Fretention-engineering-cdp",[1314],"nofollow",[1316],{"type":37,"value":1317},"CDP & Retention Engineering",{"type":37,"value":1319}," этот слой интегрируется в production pipeline.",{"type":32,"tag":40,"props":1321,"children":1323},{"id":1322},"graph-database-vs-relational-что-быстрее",[1324],{"type":37,"value":1325},"Graph Database vs Relational: что быстрее",{"type":32,"tag":33,"props":1327,"children":1328},{},[1329,1331,1337,1339,1345,1347,1353],{"type":37,"value":1330},"Хранение identity graph в relational warehouse вроде BigQuery возможно, но запросы \"найти все устройства пользователя X\" (transitive closure) дорогие. Graph database (Neo4j, Amazon Neptune, TigerGraph) работает с узлами и ребрами быстрее — запрос ",{"type":32,"tag":52,"props":1332,"children":1334},{"className":1333},[],[1335],{"type":37,"value":1336},"MATCH (u:User)-[:HAS_DEVICE]->(d:Device)",{"type":37,"value":1338}," вернет ответ за миллисекунды. В BigQuery тот же запрос пишется ",{"type":32,"tag":52,"props":1340,"children":1342},{"className":1341},[],[1343],{"type":37,"value":1344},"RECURSIVE CTE",{"type":37,"value":1346}," или ",{"type":32,"tag":52,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":37,"value":1352},"ARRAY_AGG",{"type":37,"value":1354},", но на больших таблицах использование слотов растет.",{"type":32,"tag":33,"props":1356,"children":1357},{},[1358],{"type":37,"value":1359},"Trade-off: Graph DB очень быстрая, но изменение схемы сложно, модель node\u002Fedge отличается от привычного SQL синтаксиса. Relational warehouse медленнее, но версионирование через dbt, тесты и документация легче. Большинство production сценариев используют гибридный подход: в BigQuery ежедневно batch строит таблицу identity mapping, синхронизирует в Neo4j, real-time lookup делает Neo4j. Пример pipeline: dbt model → BigQuery view → Cloud Function trigger → Neo4j Cypher INSERT.",{"type":32,"tag":77,"props":1361,"children":1363},{"className":79,"code":1362,"language":81,"meta":16,"style":16},"-- BigQuery recursive CTE для transitive closure (медленно)\nWITH RECURSIVE identity_chain AS (\n  SELECT signal_a, signal_b, 1 AS depth\n  FROM `project.dataset.identity_edges`\n  UNION ALL\n  SELECT ic.signal_a, e.signal_b, ic.depth + 1\n  FROM identity_chain ic\n  JOIN `project.dataset.identity_edges` e\n    ON ic.signal_b = e.signal_a\n  WHERE ic.depth \u003C 5\n)\nSELECT DISTINCT signal_a, signal_b\nFROM identity_chain;\n",[1364],{"type":32,"tag":52,"props":1365,"children":1366},{"__ignoreMap":16},[1367,1375,1402,1429,1442,1450,1517,1529,1547,1585,1613,1621,1634],{"type":32,"tag":87,"props":1368,"children":1369},{"class":89,"line":90},[1370],{"type":32,"tag":87,"props":1371,"children":1372},{"style":94},[1373],{"type":37,"value":1374},"-- BigQuery recursive CTE для transitive closure (медленно)\n",{"type":32,"tag":87,"props":1376,"children":1377},{"class":89,"line":100},[1378,1383,1388,1393,1397],{"type":32,"tag":87,"props":1379,"children":1380},{"style":104},[1381],{"type":37,"value":1382},"WITH",{"type":32,"tag":87,"props":1384,"children":1385},{"style":104},[1386],{"type":37,"value":1387}," RECURSIVE",{"type":32,"tag":87,"props":1389,"children":1390},{"style":155},[1391],{"type":37,"value":1392}," identity_chain ",{"type":32,"tag":87,"props":1394,"children":1395},{"style":104},[1396],{"type":37,"value":259},{"type":32,"tag":87,"props":1398,"children":1399},{"style":155},[1400],{"type":37,"value":1401}," (\n",{"type":32,"tag":87,"props":1403,"children":1404},{"class":89,"line":136},[1405,1410,1415,1420,1424],{"type":32,"tag":87,"props":1406,"children":1407},{"style":104},[1408],{"type":37,"value":1409},"  SELECT",{"type":32,"tag":87,"props":1411,"children":1412},{"style":155},[1413],{"type":37,"value":1414}," signal_a, signal_b, ",{"type":32,"tag":87,"props":1416,"children":1417},{"style":149},[1418],{"type":37,"value":1419},"1",{"type":32,"tag":87,"props":1421,"children":1422},{"style":104},[1423],{"type":37,"value":168},{"type":32,"tag":87,"props":1425,"children":1426},{"style":155},[1427],{"type":37,"value":1428}," depth\n",{"type":32,"tag":87,"props":1430,"children":1431},{"class":89,"line":145},[1432,1437],{"type":32,"tag":87,"props":1433,"children":1434},{"style":104},[1435],{"type":37,"value":1436},"  FROM",{"type":32,"tag":87,"props":1438,"children":1439},{"style":125},[1440],{"type":37,"value":1441}," `project.dataset.identity_edges`\n",{"type":32,"tag":87,"props":1443,"children":1444},{"class":89,"line":176},[1445],{"type":32,"tag":87,"props":1446,"children":1447},{"style":104},[1448],{"type":37,"value":1449},"  UNION ALL\n",{"type":32,"tag":87,"props":1451,"children":1452},{"class":89,"line":203},[1453,1457,1462,1466,1471,1475,1480,1484,1489,1493,1498,1502,1507,1512],{"type":32,"tag":87,"props":1454,"children":1455},{"style":104},[1456],{"type":37,"value":1409},{"type":32,"tag":87,"props":1458,"children":1459},{"style":149},[1460],{"type":37,"value":1461}," ic",{"type":32,"tag":87,"props":1463,"children":1464},{"style":155},[1465],{"type":37,"value":158},{"type":32,"tag":87,"props":1467,"children":1468},{"style":149},[1469],{"type":37,"value":1470},"signal_a",{"type":32,"tag":87,"props":1472,"children":1473},{"style":155},[1474],{"type":37,"value":446},{"type":32,"tag":87,"props":1476,"children":1477},{"style":149},[1478],{"type":37,"value":1479},"e",{"type":32,"tag":87,"props":1481,"children":1482},{"style":155},[1483],{"type":37,"value":158},{"type":32,"tag":87,"props":1485,"children":1486},{"style":149},[1487],{"type":37,"value":1488},"signal_b",{"type":32,"tag":87,"props":1490,"children":1491},{"style":155},[1492],{"type":37,"value":446},{"type":32,"tag":87,"props":1494,"children":1495},{"style":149},[1496],{"type":37,"value":1497},"ic",{"type":32,"tag":87,"props":1499,"children":1500},{"style":155},[1501],{"type":37,"value":158},{"type":32,"tag":87,"props":1503,"children":1504},{"style":149},[1505],{"type":37,"value":1506},"depth",{"type":32,"tag":87,"props":1508,"children":1509},{"style":104},[1510],{"type":37,"value":1511}," +",{"type":32,"tag":87,"props":1513,"children":1514},{"style":149},[1515],{"type":37,"value":1516}," 1\n",{"type":32,"tag":87,"props":1518,"children":1519},{"class":89,"line":224},[1520,1524],{"type":32,"tag":87,"props":1521,"children":1522},{"style":104},[1523],{"type":37,"value":1436},{"type":32,"tag":87,"props":1525,"children":1526},{"style":155},[1527],{"type":37,"value":1528}," identity_chain ic\n",{"type":32,"tag":87,"props":1530,"children":1531},{"class":89,"line":26},[1532,1537,1542],{"type":32,"tag":87,"props":1533,"children":1534},{"style":104},[1535],{"type":37,"value":1536},"  JOIN",{"type":32,"tag":87,"props":1538,"children":1539},{"style":125},[1540],{"type":37,"value":1541}," `project.dataset.identity_edges`",{"type":32,"tag":87,"props":1543,"children":1544},{"style":155},[1545],{"type":37,"value":1546}," e\n",{"type":32,"tag":87,"props":1548,"children":1549},{"class":89,"line":285},[1550,1555,1559,1563,1567,1571,1576,1580],{"type":32,"tag":87,"props":1551,"children":1552},{"style":104},[1553],{"type":37,"value":1554},"    ON",{"type":32,"tag":87,"props":1556,"children":1557},{"style":149},[1558],{"type":37,"value":1461},{"type":32,"tag":87,"props":1560,"children":1561},{"style":155},[1562],{"type":37,"value":158},{"type":32,"tag":87,"props":1564,"children":1565},{"style":149},[1566],{"type":37,"value":1488},{"type":32,"tag":87,"props":1568,"children":1569},{"style":104},[1570],{"type":37,"value":328},{"type":32,"tag":87,"props":1572,"children":1573},{"style":149},[1574],{"type":37,"value":1575}," e",{"type":32,"tag":87,"props":1577,"children":1578},{"style":155},[1579],{"type":37,"value":158},{"type":32,"tag":87,"props":1581,"children":1582},{"style":149},[1583],{"type":37,"value":1584},"signal_a\n",{"type":32,"tag":87,"props":1586,"children":1587},{"class":89,"line":304},[1588,1593,1597,1601,1605,1609],{"type":32,"tag":87,"props":1589,"children":1590},{"style":104},[1591],{"type":37,"value":1592},"  WHERE",{"type":32,"tag":87,"props":1594,"children":1595},{"style":149},[1596],{"type":37,"value":1461},{"type":32,"tag":87,"props":1598,"children":1599},{"style":155},[1600],{"type":37,"value":158},{"type":32,"tag":87,"props":1602,"children":1603},{"style":149},[1604],{"type":37,"value":1506},{"type":32,"tag":87,"props":1606,"children":1607},{"style":104},[1608],{"type":37,"value":948},{"type":32,"tag":87,"props":1610,"children":1611},{"style":149},[1612],{"type":37,"value":710},{"type":32,"tag":87,"props":1614,"children":1615},{"class":89,"line":345},[1616],{"type":32,"tag":87,"props":1617,"children":1618},{"style":155},[1619],{"type":37,"value":1620},")\n",{"type":32,"tag":87,"props":1622,"children":1623},{"class":89,"line":371},[1624,1629],{"type":32,"tag":87,"props":1625,"children":1626},{"style":104},[1627],{"type":37,"value":1628},"SELECT DISTINCT",{"type":32,"tag":87,"props":1630,"children":1631},{"style":155},[1632],{"type":37,"value":1633}," signal_a, signal_b\n",{"type":32,"tag":87,"props":1635,"children":1636},{"class":89,"line":872},[1637,1641],{"type":32,"tag":87,"props":1638,"children":1639},{"style":104},[1640],{"type":37,"value":272},{"type":32,"tag":87,"props":1642,"children":1643},{"style":155},[1644],{"type":37,"value":1645}," identity_chain;\n",{"type":32,"tag":33,"props":1647,"children":1648},{},[1649],{"type":37,"value":1650},"Этот запрос следует цепочке максимум на 5 уровней (depth). Без контроля depth может быть бесконечный цикл — если есть циклическая связь A → B → A. Graph DB встроенно справляется с циклами, в BigQuery нужно добавить WHERE condition вручную. Если identity graph доходит до 10M+ ребер, выделенная система вроде Neo4j более управляема. На масштабе до 1M ребер BigQuery + dbt достаточно.",{"type":32,"tag":40,"props":1652,"children":1654},{"id":1653},"privacy-и-consent-юридические-границы-identity-graph",[1655],{"type":37,"value":1656},"Privacy и Consent: юридические границы Identity Graph",{"type":32,"tag":33,"props":1658,"children":1659},{},[1660],{"type":37,"value":1661},"Identity resolution попадает в определение \"профилирование\" в GDPR (ст. 4(4)). Без согласия пользователя детерминированное + probabilistic связывание — юридический риск. Consent Mode v2 (Google) разделяет \"analytics_storage\" и \"ad_storage\", но для identity stitching может потребоваться доп. категория \"personalization_storage\". В TCF 2.2 нужно получить Purpose 1 (device storage) + Purpose 9 (personalized ads) — без них даже hash matching незаконен.",{"type":32,"tag":33,"props":1663,"children":1664},{},[1665],{"type":37,"value":1666},"Хешированный email в GDPR считается \"псевдонимизированными данными\" (Recital 26) — остается персональными данными. Если через rainbow table или reverse lookup можно вернуть plaintext, это не \"анонимизация\", а \"псевдонимизация\". Добавьте salt к хешам (email + site-specific secret → SHA-256) и храните salt в HSM (Hardware Security Module) или Secret Manager. Когда пользователь потребует \"отсоединить\" (GDPR ст. 18 restriction), удалите edges этого пользователя из identity graph и разорвите детерминированную связь.",{"type":32,"tag":33,"props":1668,"children":1669},{},[1670,1672,1678,1680,1685,1687,1693,1695,1701],{"type":37,"value":1671},"По KVKK ст. 7 нужна явная согласие: \"Кеший билгилердин иштетилишине байланышкан айбык розалуу, белгилүүлүк айбыктуу, маалымдандырылганга негизделген жана озгүч эменелүүлүккө билинген розалууу.\" Identity stitching должна быть указана как отдельный пункт в форме согласия — \"лучший опыт\" слишком генеричный. Когда пользователь отозвет согласие (",{"type":32,"tag":52,"props":1673,"children":1675},{"className":1674},[],[1676],{"type":37,"value":1677},"consent_revoked_at",{"type":37,"value":1679}," timestamp), удалите все edges этого ",{"type":32,"tag":52,"props":1681,"children":1683},{"className":1682},[],[1684],{"type":37,"value":1067},{"type":37,"value":1686}," из identity graph и установите флаг ",{"type":32,"tag":52,"props":1688,"children":1690},{"className":1689},[],[1691],{"type":37,"value":1692},"deleted_at",{"type":37,"value":1694},". В BigQuery сделайте soft delete — вместо физического удаления фильтруйте ",{"type":32,"tag":52,"props":1696,"children":1698},{"className":1697},[],[1699],{"type":37,"value":1700},"WHERE deleted_at IS NULL",{"type":37,"value":158},{"type":32,"tag":40,"props":1703,"children":1705},{"id":1704},"реализация-incremental-identity-pipeline-на-dbt",[1706],{"type":37,"value":1707},"Реализация: Incremental Identity Pipeline на dbt",{"type":32,"tag":33,"props":1709,"children":1710},{},[1711],{"type":37,"value":1712},"В production identity resolution должна работать инкрементально, не batch — ежедневно добавляйте новые сигналы, обновляйте текущий graph. Инкрементальная модель dbt:",{"type":32,"tag":77,"props":1714,"children":1716},{"className":79,"code":1715,"language":81,"meta":16,"style":16},"{{\n  config(\n    materialized='incremental',\n    unique_key='edge_id',\n    partition_by={'field': 'created_date', 'data_type': 'date'},\n    cluster_by=['signal_a_type', 'signal_b_type']\n  )\n}}\n\nWITH new_edges AS (\n  SELECT\n    GENERATE_UUID() AS edge_id,\n    a.signal_id AS signal_a,\n    a.signal_type AS signal_a_type,\n    b.signal_id\n",[1717],{"type":32,"tag":52,"props":1718,"children":1719},{"__ignoreMap":16},[1720,1728,1736,1758,1779,1834,1851,1859,1867,1876,1896,1904,1921,1947,1972],{"type":32,"tag":87,"props":1721,"children":1722},{"class":89,"line":90},[1723],{"type":32,"tag":87,"props":1724,"children":1725},{"style":155},[1726],{"type":37,"value":1727},"{{\n",{"type":32,"tag":87,"props":1729,"children":1730},{"class":89,"line":100},[1731],{"type":32,"tag":87,"props":1732,"children":1733},{"style":155},[1734],{"type":37,"value":1735},"  config(\n",{"type":32,"tag":87,"props":1737,"children":1738},{"class":89,"line":136},[1739,1744,1749,1754],{"type":32,"tag":87,"props":1740,"children":1741},{"style":155},[1742],{"type":37,"value":1743},"    materialized",{"type":32,"tag":87,"props":1745,"children":1746},{"style":104},[1747],{"type":37,"value":1748},"=",{"type":32,"tag":87,"props":1750,"children":1751},{"style":125},[1752],{"type":37,"value":1753},"'incremental'",{"type":32,"tag":87,"props":1755,"children":1756},{"style":155},[1757],{"type":37,"value":221},{"type":32,"tag":87,"props":1759,"children":1760},{"class":89,"line":145},[1761,1766,1770,1775],{"type":32,"tag":87,"props":1762,"children":1763},{"style":155},[1764],{"type":37,"value":1765},"    unique_key",{"type":32,"tag":87,"props":1767,"children":1768},{"style":104},[1769],{"type":37,"value":1748},{"type":32,"tag":87,"props":1771,"children":1772},{"style":125},[1773],{"type":37,"value":1774},"'edge_id'",{"type":32,"tag":87,"props":1776,"children":1777},{"style":155},[1778],{"type":37,"value":221},{"type":32,"tag":87,"props":1780,"children":1781},{"class":89,"line":176},[1782,1787,1791,1796,1801,1806,1811,1815,1820,1824,1829],{"type":32,"tag":87,"props":1783,"children":1784},{"style":155},[1785],{"type":37,"value":1786},"    partition_by",{"type":32,"tag":87,"props":1788,"children":1789},{"style":104},[1790],{"type":37,"value":1748},{"type":32,"tag":87,"props":1792,"children":1793},{"style":155},[1794],{"type":37,"value":1795},"{",{"type":32,"tag":87,"props":1797,"children":1798},{"style":125},[1799],{"type":37,"value":1800},"'field'",{"type":32,"tag":87,"props":1802,"children":1803},{"style":155},[1804],{"type":37,"value":1805},": ",{"type":32,"tag":87,"props":1807,"children":1808},{"style":125},[1809],{"type":37,"value":1810},"'created_date'",{"type":32,"tag":87,"props":1812,"children":1813},{"style":155},[1814],{"type":37,"value":446},{"type":32,"tag":87,"props":1816,"children":1817},{"style":125},[1818],{"type":37,"value":1819},"'data_type'",{"type":32,"tag":87,"props":1821,"children":1822},{"style":155},[1823],{"type":37,"value":1805},{"type":32,"tag":87,"props":1825,"children":1826},{"style":125},[1827],{"type":37,"value":1828},"'date'",{"type":32,"tag":87,"props":1830,"children":1831},{"style":155},[1832],{"type":37,"value":1833},"},\n",{"type":32,"tag":87,"props":1835,"children":1836},{"class":89,"line":203},[1837,1842,1846],{"type":32,"tag":87,"props":1838,"children":1839},{"style":155},[1840],{"type":37,"value":1841},"    cluster_by",{"type":32,"tag":87,"props":1843,"children":1844},{"style":104},[1845],{"type":37,"value":1748},{"type":32,"tag":87,"props":1847,"children":1848},{"style":155},[1849],{"type":37,"value":1850},"['signal_a_type', 'signal_b_type']\n",{"type":32,"tag":87,"props":1852,"children":1853},{"class":89,"line":224},[1854],{"type":32,"tag":87,"props":1855,"children":1856},{"style":155},[1857],{"type":37,"value":1858},"  )\n",{"type":32,"tag":87,"props":1860,"children":1861},{"class":89,"line":26},[1862],{"type":32,"tag":87,"props":1863,"children":1864},{"style":155},[1865],{"type":37,"value":1866},"}}\n",{"type":32,"tag":87,"props":1868,"children":1869},{"class":89,"line":285},[1870],{"type":32,"tag":87,"props":1871,"children":1873},{"emptyLinePlaceholder":1872},true,[1874],{"type":37,"value":1875},"\n",{"type":32,"tag":87,"props":1877,"children":1878},{"class":89,"line":304},[1879,1883,1888,1892],{"type":32,"tag":87,"props":1880,"children":1881},{"style":104},[1882],{"type":37,"value":1382},{"type":32,"tag":87,"props":1884,"children":1885},{"style":155},[1886],{"type":37,"value":1887}," new_edges ",{"type":32,"tag":87,"props":1889,"children":1890},{"style":104},[1891],{"type":37,"value":259},{"type":32,"tag":87,"props":1893,"children":1894},{"style":155},[1895],{"type":37,"value":1401},{"type":32,"tag":87,"props":1897,"children":1898},{"class":89,"line":345},[1899],{"type":32,"tag":87,"props":1900,"children":1901},{"style":104},[1902],{"type":37,"value":1903},"  SELECT\n",{"type":32,"tag":87,"props":1905,"children":1906},{"class":89,"line":371},[1907,1912,1916],{"type":32,"tag":87,"props":1908,"children":1909},{"style":155},[1910],{"type":37,"value":1911},"    GENERATE_UUID() ",{"type":32,"tag":87,"props":1913,"children":1914},{"style":104},[1915],{"type":37,"value":259},{"type":32,"tag":87,"props":1917,"children":1918},{"style":155},[1919],{"type":37,"value":1920}," edge_id,\n",{"type":32,"tag":87,"props":1922,"children":1923},{"class":89,"line":872},[1924,1929,1933,1938,1942],{"type":32,"tag":87,"props":1925,"children":1926},{"style":149},[1927],{"type":37,"value":1928},"    a",{"type":32,"tag":87,"props":1930,"children":1931},{"style":155},[1932],{"type":37,"value":158},{"type":32,"tag":87,"props":1934,"children":1935},{"style":149},[1936],{"type":37,"value":1937},"signal_id",{"type":32,"tag":87,"props":1939,"children":1940},{"style":104},[1941],{"type":37,"value":168},{"type":32,"tag":87,"props":1943,"children":1944},{"style":155},[1945],{"type":37,"value":1946}," signal_a,\n",{"type":32,"tag":87,"props":1948,"children":1949},{"class":89,"line":890},[1950,1954,1958,1963,1967],{"type":32,"tag":87,"props":1951,"children":1952},{"style":149},[1953],{"type":37,"value":1928},{"type":32,"tag":87,"props":1955,"children":1956},{"style":155},[1957],{"type":37,"value":158},{"type":32,"tag":87,"props":1959,"children":1960},{"style":149},[1961],{"type":37,"value":1962},"signal_type",{"type":32,"tag":87,"props":1964,"children":1965},{"style":104},[1966],{"type":37,"value":168},{"type":32,"tag":87,"props":1968,"children":1969},{"style":155},[1970],{"type":37,"value":1971}," signal_a_type,\n",{"type":32,"tag":87,"props":1973,"children":1974},{"class":89,"line":908},[1975,1980,1984],{"type":32,"tag":87,"props":1976,"children":1977},{"style":149},[1978],{"type":37,"value":1979},"    b",{"type":32,"tag":87,"props":1981,"children":1982},{"style":155},[1983],{"type":37,"value":158},{"type":32,"tag":87,"props":1985,"children":1986},{"style":149},[1987],{"type":37,"value":1988},"signal_id\n",{"type":32,"tag":1990,"props":1991,"children":1992},"style",{},[1993],{"type":37,"value":1994},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":16,"searchDepth":136,"depth":136,"links":1996},[1997,1998,1999,2000,2001,2002],{"id":42,"depth":100,"text":45},{"id":472,"depth":100,"text":475},{"id":1079,"depth":100,"text":1082},{"id":1322,"depth":100,"text":1325},{"id":1653,"depth":100,"text":1656},{"id":1704,"depth":100,"text":1707},"markdown","content:ru:data:identity-resolution-6-signalov-ednom-lichnosti.md","content","ru\u002Fdata\u002Fidentity-resolution-6-signalov-ednom-lichnosti.md","ru\u002Fdata\u002Fidentity-resolution-6-signalov-ednom-lichnosti","md",1782079503338]