마이그레이션은 무엇보다 먼저 품질 프로젝트입니다
19개 언어로도 제공
English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Українська · Español (México) · Français (Canada) · Deutsch (Schweiz)

Data Architect 과정 10장인 마이그레이션과 동기화의 모듈 1/5. 각 모듈은 독립적으로 읽을 수 있습니다. 이전: 지난 장, 통합과 데이터 이동 · 다음: 대용량 적재
이 모듈이 답하는 질문: Salesforce에 적재를 시작하기 전에 데이터에 무슨 일이 일어나야 할까요?
마이그레이션 프로젝트는 사람을 속일 수 있습니다. 데이터가 여기 있고, 저기 필요하니, 누군가 Data Loader, Bulk API, CSV 파일, 배치 크기, 적재 순서 이야기를 시작합니다. 그런 것들은 중요합니다. 하지만 제가 시작하는 곳은 아닙니다. 제 첫 질문은 이것입니다. 우리는 정확히 무엇을 옮기려는 걸까요? 원본에 중복 고객, 잘못된 주소, 낡은 값, 깨진 관계, 아무도 필요로 하지 않는 15년치 데이터가 있다면, Salesforce는 기꺼이 그 모든 것의 새 집이 될 겁니다. 더 빨리 적재한다고 그게 고쳐지지는 않습니다. 마이그레이션은 무엇보다 먼저 품질 프로젝트입니다.
Start With the Picture
섹션 제목: “Start With the Picture”Here’s Steve Trucking’s landscape from Checkpoint 1, the weekend RouteDesk retires. RouteDesk is the desktop dispatch tool the coordinators used inside each distribution center (DC) to turn manifests into routes. It holds eight years of delivery history, about 5 million deliveries, and the quality varies by DC. At Checkpoint 1 we decided it retires, and we left one question open: what, if anything, comes into the org? That’s a migration decision, and this is the chapter for it. ⟲
One new arrow. It runs once, and then it disappears. ⟲
A migration is an arrow on the landscape like any other. Everything chapter 9 asked of an arrow applies: what moves, how much, by which key, who proves it arrived. The difference is that this arrow has an end. When it’s done, RouteDesk is switched off and the arrow comes off the drawing. That makes it easy to rush, because “we only do it once.” But the data it carries stays in Salesforce for years. ⟲
나쁜 데이터를 더 빨리 옮기는 것은 성공이 아닙니다
섹션 제목: “나쁜 데이터를 더 빨리 옮기는 것은 성공이 아닙니다 ”레거시 시스템에 고객 레코드가 50만 개 있고, 우리는 고객 레코드 50만 개를 마이그레이션합니다. 성공했나요? 그럴 수도 있습니다. 그런데 4만 개가 중복이고, 7만 5,000개는 10년 동안 활동이 없었고, 수천 개는 주 코드가 잘못되었고, 일부는 쓸 만한 식별자가 없고, 일부 자식은 더 이상 없는 부모를 가리키고, 일부 필드는 레코드가 언제 만들어졌느냐에 따라 뜻이 다르다면요? 보고서는 여전히 원본 50만, 대상 50만, 100퍼센트 적재라고 말할 수 있고, 프로젝트는 여전히 실패일 수 있습니다. 완전성은 중요하지만, 완전성만으로 품질이 증명되지는 않습니다.
그래서 적재를 설계하기 전에 저는 원본을 이해하고 싶습니다. 어떤 데이터가 있고, 무엇을 뜻하나요? 얼마나 오래되었고, 얼마나 믿을 만하고, 어떤 필드가 실제로 쓰이고, 어떤 값이 유효하고, 어떤 관계가 있고, 어떤 식별자를 믿을 수 있나요? 마이그레이션에서 무엇이 살아남아야 하고, 무엇이 그러지 말아야 하나요? 앞선 장들이 여기서 청구서를 내밉니다. 4장은 엔터프라이즈 랜드스케이프를, 5장은 품질이 설계되어야 한다는 것을, 6장은 정체성과 권한 원천을 가르쳤습니다. 마이그레이션은 그 모두를 기존 데이터에 적용합니다. 그냥 행을 옮기는 일이 아닙니다. 과거의 어느 부분이 미래 아키텍처의 일부가 될 자격이 있는지 정하는 일입니다.
마이그레이션, 아카이브, 폐기, 그리고 그 이유
섹션 제목: “마이그레이션, 아카이브, 폐기, 그리고 그 이유 ”마이그레이션 목록에는 최소한 세 가지 답이 필요합니다. 마이그레이션, 아카이브, 또는 정책에 따른 폐기. 5년 된 트랜잭션 세부 사항은 활성 데이터 모델에 두지 않으면서도 컴플라이언스 때문에 보관해야 할 수 있고, 낡은 임시 데이터에는 보존 요구사항도 가치도 없을 수 있고, 이력은 검색 가능한 아카이브에 속할 수 있습니다. 7장의 수명 주기 원칙은 “출구를 설계하라”였고, 마이그레이션은 그것을 적용할 완벽한 때입니다. 그냥 거기 있다는 이유로 모든 레코드를 들고 가지 마십시오.
So zoom in on RouteDesk and take it apart, one class of data at a time. ⟲
Every class of data gets a decision, a place and a reason. ⟲
The deliveries not yet made have to come in: manifests arrive one to two days ahead, so on cutover weekend RouteDesk holds about two days of work, roughly 6,400 deliveries, and the crews need them on Monday morning. The recent history comes in because of claims. A damage claim is a Case in Salesforce, and the agent working it needs the delivery behind it. So deliveries still inside the claim window come in too. Steve Trucking accepts claims for 60 days after a delivery, so that’s about 190,000 more Work Orders. Had the business said 30 days, it would be half that. The window is the business’s number, not ours. ⟲
The other 4.8 million deliveries go to Snowflake, where Checkpoint 1 already sends status history, kept by the partner key so a claim on an old delivery can still find it, and so leadership’s five-year reports still work. They don’t belong in the operational core: that would make Salesforce RouteDesk’s retirement home, and chapter 7 showed what Work Orders at volume cost. And the route plans and the coordinators’ drafts? Eight years of yesterday’s plans have no value once the deliveries are done. But I don’t decide that alone. ⟲
The opposite mistake is “we don’t need the old stuff.” Who decided? Legal, finance, operations, service, compliance? The data architect shouldn’t invent retention policy during a migration; we translate the business and regulatory requirement into architecture. Before excluding data, establish whether it must be kept, for how long, where, who needs access, and whether its relationships and source identifiers must survive. Eight years of Recipients’ names, addresses and phone numbers is exactly that kind of question: archiving them isn’t the same as keeping them forever. The goal isn’t to migrate less. It’s to know why every class of data is moving, or isn’t. ⟲
Test knowledge. Migrate what the new system needs to operate, not everything the old one held. Expect a scenario with years of legacy history: the answer is usually to migrate active and recent records and archive the rest outside Salesforce where it stays reachable, with the retention decision made by the business, not by the migration team. ⟲
Where the Preparation Happens
섹션 제목: “Where the Preparation Happens”Before the steps, the place. All of this preparation happens outside Salesforce, in a working database of its own: Postgres, SQL Server, Oracle, MySQL, even SQLite for a small job, whatever the team knows. Not in Salesforce, and not in a spreadsheet that gets emailed around. I call it the preparation data store, or the preparation store for short. It sits in between: the source feeds it, and it feeds Salesforce. ⟲
The preparation data store sits in between. Every step in this module happens inside it. ⟲
The extract lands there raw. The standardizing, cleaning, enriching, deduping and validating all run there, as code. The quarantine is a table, the counts are queries, and the whole thing can be run again from the top. Some tools connect a database like this straight to Salesforce, copying data down and sending changes back; others export files for a data loader. There are many ways to load data. The principle doesn’t change: prepare it outside, then load the result. ⟲
And it holds more than the source. Pull down the relevant parts of the target org too. Why? Because dedupe has to compare against what’s already in Salesforce, and when the survivor of a merge is a record that’s already there, the new children need its key to link to it. You can’t decide the merge without both sides in front of you. For RouteDesk, the preparation store holds the RouteDesk extract and a copy of what Salesforce already has: the Retail Partner Accounts, the Products and Service Territories, the claim Cases with their delivery references, and the Work Orders the new integration has already created, because the partners don’t stop sending manifests for our cutover weekend. ⟲
Then you practice. Run the preparation, load a sandbox, reconcile, find the rule that was wrong, fix it, run it all again. By the time we reach production, the preparation has run many times, and it’s boring. That’s the goal. ⟲
제 순서: 표준화, 정제, 보강, 중복 제거, 검증
섹션 제목: “제 순서: 표준화, 정제, 보강, 중복 제거, 검증 ”When I’m preparing data for migration, I work in this order, and the order matters. All five steps happen in the preparation data store. ⟲
Standardize. Get equivalent values into one form. One source has CA, California and Calif.; another has US, USA and United States. A company comes in as Steve Plumbing, Steve's Plumbing and Steve's Plumbing LLC. Phone numbers arrive as 5555550142, (555) 555-0142 and +1 555 555 0142. Before we compare records or apply matching rules, we need to know which differences are formatting and which are meaningful. ⟲
Names are the classic trap. I had a system with first and last name in one field, and the Salesforce contact needs them apart. “Daniel Reyes” splits easily. Then you get “Mr. Daniel Reyes,” “Daniel Reyes PhD,” “Daniel Reyes III,” and names with two family names, such as Roberto González Suárez, where González isn’t a middle name: split that wrong and you’re in trouble. Build the patterns (two words, three words, a title, a suffix), run the splits, and have the customer validate the results. ⟲
정제. 틀리거나, 쓸 수 없거나, 낡은 것을 다룹니다. 잘못된 코드, 불가능한 날짜, 오타, 자리 표시 값, 필드의 뜻과 맞지 않는 데이터가 든 필드. 선택 목록 값은 의도적으로 매핑하십시오. 레거시 리드 상태 Cold가 대상에서는 Closed가 될 수도 있습니다. 목록이 길다면(저는 200개 값을 본 적이 있습니다) 변환 표를 만들고 원본 값마다 대상 값을 비즈니스가 채우게 하십시오. Salesforce는 선택 목록을 엄격하게 검증하니, 도착하기 전에 잡아내고, 원본에 무엇이 들어 있는지 유효성 검사 규칙이 알려 주기를 기다리지 마십시오.
RouteDesk’s “quality varies by DC” shows up right here. Each DC set up its own status codes over eight years, so the same outcome arrives in nine spellings. The transformation table maps every one of them to the Work Order’s status values in Salesforce: ⟲
| DC | RouteDesk says | Work Order status |
|---|---|---|
| DC 1 | DLV | Completed |
| DC 4 | Delivered - OK | Completed |
| DC 7 | DONE/INST | Completed (the install is on its line item) |
| DC 1 | NH | Cannot Complete (nobody home) |
| DC 4 | Refused | Cannot Complete |
| DC 7 | CXL | Canceled |
The left two columns come from profiling the extract; the right column comes from the business, not from us. Completed, Cannot Complete and Canceled are three of the standard Work Order status values (WorkOrder (새 탭에서 열림), Object Reference, Winter ‘27, checked 2026-10-27). Notice the third row: one RouteDesk code carried two facts, the delivery and the install, and the target model keeps them apart. ⟲
Enrich. Sometimes missing information can be reliably added: a normalized address, a postal code from city and state, a county, a geolocation, a mapping from a legacy code to the new enterprise taxonomy, an enterprise identifier. Enrichment needs provenance. If we add or change information, I want to know where it came from and why I trust it. Some of RouteDesk’s older deliveries don’t name the Retail Partner at all, because each DC served one partner and everybody knew. The DC and the order number’s format tell us which partner it was. That’s enrichment from a rule we can show, not a guess. ⟲
중복 제거. 그다음 현실의 같은 대상을 나타내는 레코드를 찾습니다. 왜 여기서 시작하지 않을까요? 더러운 데이터를 매칭하는 것이 더 어렵기 때문입니다. Steve's Plumbing과 STEVES PLUMBING LLC는 표준화한 뒤에 훨씬 비교하기 쉬워집니다. 들어오는 데이터 안에서 중복을 제거하고, 그다음 이미 Salesforce에 있는 것과 비교하십시오. 6장의 규칙은 여전히 유효합니다. 병합은 파괴적이고, 연결은 그렇지 않습니다. 퍼지 점수가 그럴듯해 보인다고 레코드를 합치지 마십시오.
Validate. Finally, test the transformed data against the target: required information present, reference values valid, relationships resolvable, keys unique where they should be, values fitting the model, authority rules preserved. Only then do I want to talk seriously about loading. And don’t expect the import tool to catch everything. Salesforce’s own Trailhead project on the NPSP importer makes the point: it catches invalid picklist values and missing required fields, but if a spreadsheet turned a postal code like 02134 into the number 2134, the importer loads the four digits (Perform an Import Dry Run (새 탭에서 열림), Trailhead, checked 2026-10-27). That’s one more reason the preparation lives in a database with typed columns, not in a spreadsheet. ⟲
Five steps, in order. A record that fails one goes somewhere visible, with its reason. ⟲
Test knowledge. Data quality is fixed before the load, not after. Know the preparation steps (standardize, clean, enrich, deduplicate, validate) and why the order matters: you can’t match records reliably until their values are in one form. Picklist values are mapped with a transformation table the business signs off, because Salesforce rejects values a restricted picklist doesn’t have. ⟲
옮기기 전에 정제하십시오
섹션 제목: “옮기기 전에 정제하십시오 ”유혹은 이것입니다. “일단 전부 Salesforce에 넣고 나중에 정리하죠.” 기본값으로는 좋아하지 않습니다. 나쁜 데이터가 운영 환경에 들어가면 운영에 참여합니다. 사용자가 보고, 자동화, 보고서, 통합, 에이전트가 보고, 중복이 관련 레코드를 모으기 시작하고, 정리는 더 어려워집니다. 가능한 곳에서는 대상에 들어가기 전에 데이터를 개선하십시오. 과거의 모든 결함을 고칠 필요는 없습니다. 비용 대비 효과의 결정입니다. 하지만 “나중에 정리할게요”는 마이그레이션 전략이 아닙니다. 출시일이 정해진 기술 부채입니다.
And not every record deserves the same effort. An active customer with open orders, open cases, current contracts and billing relationships is different from one who bought something once nine years ago. Both may need to be kept. For the critical, active data I may require stricter validation, more enrichment, closer duplicate review and detailed reconciliation; for low-value history, preserving traceability may matter more than making every record perfect. Architecture is partly deciding where quality effort creates value. For RouteDesk, the 6,400 deliveries the crews will drive to on Monday get the strictest checks. The 4.8 million going to the archive need their keys and their dates right; nobody will fix eight years of typos in delivery notes. ⟲
원본 정체성을 지키고, 키로 적재하십시오
섹션 제목: “원본 정체성을 지키고, 키로 적재하십시오 ”가장 쉬운 실수 중 하나는 Salesforce 레코드를 원래 출처까지 거슬러 추적하는 능력을 잃는 것입니다. 레거시 고객 CUST-847291이 계정 001…이 되어도, 저는 그것이 CUST-847291에서 왔다는 것을 여전히 알고 싶습니다. 대사, 문제 해결, 재적재, 감사, 자식 레코드 매칭, 롤백 분석, 그리고 출시 뒤에 오는 질문들을 위해서요. 새 Salesforce ID는 Salesforce 안에서 중요하지만 원본 정체성을 지우지는 않습니다. 9장의 외부 ID 원칙입니다. 마이그레이션과 통합은 정체성에서 만납니다.
At Steve Trucking they meet in one field. Every Work Order already carries the partner’s key, Partner_Delivery_Key__c, an External ID marked unique, holding values like REDROCK-8472914-1 (chapter 9, module 2). RouteDesk kept the partner’s order number on each delivery, so the migration builds the same key and upserts on it, exactly as the integration does. That matters on cutover weekend: if Redrock resends a manifest for Tuesday after we’ve loaded Tuesday from RouteDesk, the integration finds the migrated Work Order and updates it instead of creating a second one. RouteDesk’s own delivery number comes along too, in a plain field, so anyone can trace a Work Order back to the record it came from. ⟲
So don’t rebuild relationships by name (“find the Account whose Name is Acme Distribution”). If the legacy contact carries Legacy_Account_ID = CUST-847291 and the Salesforce Account carries that identifier as an External ID, the relationship is rebuilt deterministically. The Bulk API does this in the load file itself: a column header such as WorkOrder.Partner_Delivery_Key__c says “find my parent by this indexed field,” and Salesforce looks up the parent’s ID for you (Relationship Fields in a Header Row (새 탭에서 열림), Bulk API 2.0 and Bulk API Developer Guide, checked 2026-10-27). Keys turn “I think this child belongs here” into “I know which parent this came from,” and that matters more as the Number of Zeros grows. ⟲
Relationships also create sequence. If contacts reference accounts, the accounts must exist first; if line items reference orders and products, those come first. So migration isn’t one giant load. It’s reference data, parents, children, junctions, then dependent history, in an order the target data model dictates. That’s one more reason the data architect belongs in migration planning: the model tells us how the migration has to be assembled. Here’s RouteDesk’s open work, on Checkpoint 1’s model. ⟲
Wave 1: what the Work Orders will point to has to exist first. Most of it already does. ⟲
Wave 2: the Work Orders, upserted by the partner key. ⟲
Wave 3: the children, each finding its Work Order by the same key. ⟲
Wave 4: the claim Cases already in Salesforce get their link to the delivery. The model sets the order. ⟲
Test knowledge. Keep each legacy record’s key in an External ID field, load parents before children, and let each child find its parent by that key: an upsert on the External ID, and a relationship column in the load file (
Parent.External_Id__c) instead of looking up Salesforce IDs. Reloads then update instead of duplicating, and every record traces back to its source. ⟲
병합된 레코드에는 자식 전략이 필요합니다
섹션 제목: “병합된 레코드에는 자식 전략이 필요합니다 ”사람들이 과소평가하는 문제가 이것입니다. 분석 결과 레거시 고객 A, B, C가 같은 고객이어서, 대상에는 계정 하나가 생깁니다. 좋습니다. 하지만 A에는 케이스 12건, B에는 주문 4건, C에는 연락처 3개가 있습니다. 자식 매핑을 다시 설계하지 않고 부모만 개념적으로 병합하면, 부모 문제는 풀고 관계는 깨뜨린 것입니다. 모든 중복 제거 결정에는 자식 전략이 필요합니다.
RouteDesk has its own version. When a partner revised a manifest on the day, a coordinator sometimes keyed the delivery in again instead of editing it. Now RouteDesk has two deliveries with the same partner order number: one with the old window and two stops, one with the new window and the crew’s notes. Salesforce will have one Work Order, because the partner key is unique. Which window wins, and what happens to the stops and notes on the other one? ⟲
먼저 필드입니다. 두 레코드가 일치할 때 어떤 값이 이기나요? 빈 값 대 값은 쉽습니다. 충돌은 그렇지 않습니다. Steven인가요 Stephen인가요, Salesforce의 이메일인가요 적재 데이터의 이메일인가요? 살아남을 레코드를 고르고 필드마다 결정한 다음, 샘플 사례를 일찍 비즈니스 앞에 내놓아 그 선택에 비즈니스의 지문이 남게 하십시오.
Then the children. I see three options: add the children to the survivor, don’t load the merged record’s children, or load the merged record as inactive, linked to the survivor, with its children kept on it. ⟲
Three ways, none free. Notice the third one at RouteDesk: the inactive duplicate can’t reuse the partner key, because the survivor already holds it, so it needs a key of its own. ⟲
Whichever you choose, it happens in the preparation store, before anything loads. That’s where the survivor is picked, sometimes a record that’s already in Salesforce, pulled down with its key. That’s where each child gets the key of the parent it will point to. And that’s where the merged record either keeps its children, hands them over or is left out. Salesforce receives the result of the merge, not the job of doing it. ⟲
어떻게 고를까요? 데이터가 얼마나 중요한지, 그리고 적재된 것까지 추적성이 필요한지에 달려 있습니다. 그리고 병합 자체의 이점과 위험을 저울질하십시오. 소매 고객 목록에서 엉뚱한 두 사람의 구매 이력을 합치는 것은 짜증 나는 일입니다. 한 환자의 약을 다른 환자의 기록에 보여 주는 것은 심각한 위반입니다. 잘못된 매칭의 대가가 클수록 병합은 더 보수적이어야 합니다. 무엇을 결정하든, 각 자식을 여전히 원래 출처까지 추적할 수 있나요? 마이그레이션의 중복 제거는 “계정에 중복 매칭을 돌린다”가 아닙니다. 관계 그래프 전체가 중요합니다.
저는 반대편에 서 본 적이 있습니다. 대학 시절부터 이용하던 소매업체가 고객 데이터를 마이그레이션하고 있었는데, 들여다보니 Steve Simpson이 이메일 주소와 우편 주소 대여섯 개 아래에 나타났습니다. 대학 때 주소, 세 들어 살던 집, 그 뒤의 집들. 그것들을 병합해야 했을까요? 세상에는 다른 Steve Simpson들도 있습니다. 비즈니스는 저의 옛 이력을 묶는 것이 엉뚱한 Steve Simpson과 저를 병합할 위험만큼의 가치가 없다고 판단했습니다. 모든 병합이 답해야 하는 질문이 그것입니다. 데이터를 합치는 이점은 무엇이고, 엉뚱한 사람을 고를 위험은 무엇인가요?
Test knowledge. Deduplicate before the load, within the incoming data and against what’s already in Salesforce, with matching rules and a survivor chosen field by field. Expect the follow-up question: what happens to the merged record’s child records? Re-parent them to the survivor, leave them out (and archive them), or keep them on an inactive linked record. Each has a cost. ⟲
반복 가능한 변환, 보존된 원본
섹션 제목: “반복 가능한 변환, 보존된 원본 ”레거시 상태 A는 Active, I는 Inactive, S는 Suspended가 됩니다. 그 매핑은 어디에 있나요? 누군가의 기억이 아니라, 파일 세 개에 제각각 복사된 Excel 수식이 아니라, 금요일 밤의 수작업 단계가 아니라. 내일 다시 적재해도 같은 결과가 나와야 하니, 매핑, 표준화와 정제 규칙, 변환, 중복 제거 결정, 키 생성은 모두 재현 가능해야 합니다. 일부가 문자 그대로 프로그래밍 언어로 쓰이지 않았더라도, 마이그레이션 프로세스는 코드입니다.
And don’t destroy the starting point. Keep the original extract in raw tables, exactly as it came out, and never change them. Each step writes its result to a new staged table: standardized, cleaned, deduplicated, load-ready. When something looks wrong, I want to know whether it was wrong in the source, changed by our transformation, changed by the load, or changed by Salesforce automation afterward, and with every table kept I can walk back through them and find out. Overwrite your only copy of the source while cleaning it and you lose the evidence. ⟲
I learned how much this pays off on a support migration. A company was moving its support desk from Zendesk into Salesforce, and Zendesk’s tickets were very similar to Salesforce Cases, but not exact. So I loaded every Zendesk export into a SQL database as raw tables, one per Zendesk structure: organizations, users, tickets, custom fields, comments, attachments. Then I built interim tables that got closer and closer to the Salesforce structure, with the field and picklist mappings kept as tables of their own. Then I loaded Salesforce from those tables and brought the Salesforce IDs back. In the end every row had three things: its original Zendesk key, the transformations that had been applied to it, which were never one way, and its Salesforce key. That’s what let me do partial loads and reloads whenever I needed to. ⟲
Here’s the same design for RouteDesk, one step at a time. ⟲
Extract: one raw table per RouteDesk structure, each row with its RouteDesk key. These tables never change. ⟲
Generate: new tables shaped for Salesforce, built from the raw ones with the mapping tables. The raw tables are still there. ⟲
Load: the Work Orders upserted by the partner key, then their children. ⟲
Keys back: each Salesforce ID is written to its row. Now every row knows where it came from, what was done to it and where it landed. ⟲
So no transformation is allowed to lose fidelity. If a step throws information away (truncates a note, drops a code it didn’t recognize, keeps one of two conflicting values without saying which), I can’t trace back through it, and I can’t repeat the run and get the same answer. Keep the raw tables, keep the staged tables, keep what each load sent and what came back. Then you can rerun the whole thing from the raw extract at any time, and you have the history of every load. This is migration’s version of lineage: preserve where the data came from and what you did to it. ⟲
Sometimes the Staging Is Inside Salesforce
섹션 제목: “Sometimes the Staging Is Inside Salesforce”The preparation store isn’t the only place to stage. In a few special cases, the last stop before the real objects is a plain custom object inside Salesforce: one flat row per source record, no automation, loaded fast. Then a batch process works through the rows and builds the real records. I’ve used it when Salesforce’s own logic had to create the records and was too slow to load through: a scheduling process that took a few seconds per appointment. Module 3 comes back to that case. ⟲
Salesforce uses the same pattern in its own products, and it’s worth learning from. The Nonprofit Success Pack loads a spreadsheet into its NPSP Data Import object first. A dry run checks for matches without creating anything. Then the importer creates the accounts, contacts and donations, and writes each new record’s ID back onto the row it came from (How the Import Process Works (새 탭에서 열림), Salesforce Help, checked 2026-10-27). That’s a reference, not a rule: staging inside Salesforce is the special case, not the way to load everything. ⟲
For RouteDesk, a one-time move with heavy cleaning and merging, the preparation store outside Salesforce does the work, and the load sends the result. ⟲
나쁜 레코드에는 갈 곳이 필요합니다
섹션 제목: “나쁜 레코드에는 갈 곳이 필요합니다 ”레코드 50만 개 중 49만 7,800개가 검증을 통과하고 2,200개가 통과하지 못합니다. 조용히 버릴까요? 아닙니다. 필수 필드에 쓰레기를 억지로 넣을까요? 아닙니다. 모든 이력 레코드가 완벽해질 때까지 프로젝트를 멈출까요? 아마 아닐 겁니다. 저는 격리와 개선 경로를 원합니다. 어떤 원본 레코드가 왜 실패했는지, 어떤 규칙이 거부했는지, 전환 전에 고쳐야 하는지, 결정은 누가 책임지는지, 미룰 수 있는지를 기록하는 경로. 이제 예외는 숨겨진 데이터 손실이 아니라 눈에 보이는 아키텍처 작업입니다.
Before you call a record bad, look at the rule that rejected it. Sometimes the record is fine and the rule is wrong. Salesforce’s Well-Architected framework puts it plainly: “data architecture decisions determine the populations that become visible—and invisible,” and a required email address “excludes populations that don’t have reliable internet access or personal email addresses” (Fairness (새 탭에서 열림), checked 2026-10-27). RouteDesk has thousands of deliveries where the Recipient gave only a phone number. If the new Work Order requires an email, those aren’t bad records. They’re real people the rule would make invisible. Fix the rule, not the person. ⟲
그다음 적재 전에 변환을 증명하십시오. 원본 레코드 몇 개로 시작했고, 몇 개를 의도적으로 제외했고, 중복 몇 개를 통합했고, 몇 개가 준비되었고, 몇 개가 격리되었고, 상위-하위 관계는 몇 개가 해결되고, 통제 합계는 얼마인가요? 적재 전에 숫자가 맞지 않으면 더 빨리 적재해도 소용없습니다. 모듈 4는 건수, 합계, 샘플 점검, 집계 보고서로 마이그레이션을 증명하지만, 증명은 여기서 시작합니다.
AI는 정제를 도울 수 있습니다. 진실을 지어낼 수는 없습니다
섹션 제목: “AI는 정제를 도울 수 있습니다. 진실을 지어낼 수는 없습니다 ”AI는 마이그레이션에 유용합니다. 매핑을 제안하고, 의심스러운 값을 찾고, 중복 후보를 묶고, 이상을 발견하고, 변환 코드를 생성하고, 거부된 레코드의 패턴을 설명합니다. 하지만 보강 프로세스가 “이 회사는 아마 애리조나에 있을 거예요”라고 결정한다면, “아마”로는 부족합니다. 그리고 두 고객이 병합해도 될 만큼 비슷해 보인다고 결정한다면, 6장을 기억하십시오. 잘못된 매칭은 덜 매칭하는 것보다 더 큰 피해를 줄 수 있습니다. 조사를 빠르게 하는 데 AI를 쓰십시오. 권한 원천이 되는 기업 데이터를 조용히 만들어 내게 두지는 마십시오.
시험 너머: AI가 바꾸는 것. AI는 마이그레이션 중의 프로파일링, 매핑, 이상 탐지, 매칭 후보 찾기를 극적으로 빠르게 할 수 있습니다. 권한 원천이 되는 비즈니스 데이터를 만들고, 병합하고, 바꾸는 결정 주위에는 결정론적 규칙, 출처, 사람의 검토를 두십시오.
아키텍트가 여기서 결정하는 것
섹션 제목: “아키텍트가 여기서 결정하는 것 ”- 비즈니스 가치와 보존 요구사항에 따라 어떤 원본 데이터를 마이그레이션하고, 아카이브하고, 제외할지.
- Where preparation happens (a preparation store outside Salesforce, a staging object inside it, or both), and which parts of the target org are pulled down to merge against. ⟲
- 대상에 들어가기 전에 데이터를 어떻게 표준화, 정제, 보강, 중복 제거, 검증할지.
- 중요한 대상 레코드 하나하나를 추적하고 대사할 수 있도록, 어떤 원본 식별자와 계보가 살아남는지.
- The load order the target data model dictates, and the keys each child uses to find its parent. ⟲
- 중복 제거 결정이 관계 그래프 전체에 걸쳐 필드와 자식을 어떻게 다루는지, 중요도, 추적성, 잘못된 병합의 위험을 저울질하며.
- 운영 적재가 시작되기 전에 어떤 변환 규칙과 예외 처리 규칙이 반복 가능해야 하는지.
마이그레이션을 적재한 행 수로 재지 마십시오
섹션 제목: “마이그레이션을 적재한 행 수로 재지 마십시오 ”“레코드 50만 개 중 50만 개를 적재했어요”는 적재 도구가 작동했다는 뜻입니다. 저는 이것을 알고 싶습니다. 맞는 데이터를 옮겼나요, 개선해야 할 것을 개선했나요, 정체성과 관계를 지켰나요, 중복을 안전하게 통합했나요? 무엇을 제외했는지 설명하고, 변환을 재현하고, Salesforce 레코드를 원본까지 추적하고, 결과를 증명할 수 있나요? 그 일을 먼저 하십시오. 그다음에 얼마나 빨리 적재할지 걱정합시다.
더 알아보기
섹션 제목: “더 알아보기 ”- Salesforce, General Guidelines for Data Loads (새 탭에서 열림) and Relationship Fields in a Header Row (새 탭에서 열림), Bulk API 2.0 and Bulk API Developer Guide, checked 2026-11-01. ⟲
- Salesforce, WorkOrder (새 탭에서 열림), Object Reference for the Salesforce Platform, Winter ‘27 (API version 68.0), checked 2026-11-01. ⟲
- Salesforce Help, How the Import Process Works (새 탭에서 열림) (the Nonprofit Success Pack’s staging object), checked 2026-11-01. ⟲
- Hands-on: the Trailhead trail Import Data With Nonprofit Success Pack (NPSP) (새 탭에서 열림) walks through the whole staging pattern in a practice org: a template, staging rows, a dry run, fixing the failed rows, then the import. It runs in a Trailhead Playground; Trailhead notes that as of December 2025, NPSP is no longer offered as a preconfigured package in production orgs. Checked 2026-10-27. ⟲
- Salesforce Architects, Well-Architected, Fairness (새 탭에서 열림), checked 2026-11-01. ⟲
- In this course: Master Data and Identity (matching, survivorship, link vs merge), Data Quality and Governance, and Keys and Write Ownership (the partner key). ⟲
- Trailhead, Perform an Import Dry Run (새 탭에서 열림), checked 2026-11-01. ⟲
