この記事は、Sansan Data Intelligence 開発Unit ブログリレーの第3弾です。
こんにちは、技術本部 Data Intelligence Engineering Unitの Makoto Nagai です。
今までの記事では、Sansan Data Intelligence(SDI)の顧客が利用するSystemについて焦点を当てて紹介しましたが、今回はSDIが利用しているMaster Data Systemについて紹介したいと思います。
このMaster Data Systemは、Sansanで使われている名寄せ、識別、Master DataのSystemを作り替える目的で新たに作られたSystemであり、Sansan Organization Code v2(SOCv2)と呼ばれています。
その作り替えに至った経緯と設計の概要について紹介したいと思います。
目次
背景と問題
Sansanでは、名刺や企業情報、営業履歴を一元管理して全社で共有できるようにすることで、売上拡大とコスト削減を同時に実現するビジネスデータベースを提供している。 名刺や取引先情報など昔から多くの顧客情報を扱っており、顧客が持つ名刺情報や人物情報の名寄せをする仕組みが作られていた。 また、営業DXとしての営業先の企業情報の重要性からMaster Dataとして企業とその事業所の情報を提供していた。
これらを行う2つのSystemが別々に存在する。
- (1) 名寄せ辞書を用いて顧客のDataを識別、名寄せを行うSystem
- (2) 企業、事業所の情報をMaster Dataとして提供するSystem
(1)はSansan Organization Code(以下SOC)と呼ばれる企業の識別子(ID)を管理し、識別によって対応する識別子を返す。 識別子を用いて名刺に記載された企業情報や人物情報を名寄せするこのSystemは、Sansanにおいて大変重要なものである。 一方、(2)は購買Dataや自社収集Dataなどから、企業、事業所などの情報を集約し、Master Dataとして提供していた。 (1)のSystemは名刺の名寄せに始まり10年以上の歴史があり、(2)のSystemは営業DXの重要性から比較的新しく構築されたSystemである。
これら2つのSystemが独立して存在した結果、次の2つの問題が存在した。
- Problem1. 名寄せ、識別率と精度の向上に時間と労力がかかる構造になっていた
- Problem2. Dataの収集、追加、変更に対して大きな時間と労力がかかっていた
2つのSystemが抽象的に次のような相互依存関係にあり、問題の根本的な原因となっていた。
- Step1. (2)のSystemが、購買Dataの前処理や自社収集Dataの前処理を行う
- Step2. (1)のSystemで、購買Dataや自社収集Dataを識別し、名寄せをする
- Step3. (2)のSystemが、名寄せの結果を用いてMaster Dataを生成する
- Step4. (1)のSystemが、Master Dataを辞書として利用し名寄せ、識別の改善をする

例えば、新しく購買Dataや収集Dataを追加した際に、(2)のSystemの変更はStep2からStep4を通して、相互に影響しあう構造になっていた。
これらの問題は端的には、
- この2つのSystemをComponentとしてみれば、 R.C. Martin著『Clean Architecture』におけるAcyclic Dependencies Principle(ADP)に反していることがわかる。これはJohn Lakos著『Large-Scale C++ Software Design』で述べられているように、規模が大きいほどこのSystemのMaintenance costは大きくなる。
- またData Transformationの観点では、Raw Dataから辞書へのDataの流れをみた時にDirected Acyclic Graph(DAG)になっていない。
- また、これらのSystemは異なるTeamで管理されており、Engineeringの組織の中で、Conway's Law に基づくCostが開発の生産性に悪影響を与えていた。
に起因する問題であって、Systemとして根本的な改修が必要な状況にあった。
Domainの再考
Systemの構成に問題があることは明らかであるが、このSystemはSansanの中で重要な機能のうちの1つであり、会社全体で使われているため、これらを根本的に作り直すためには合理的でよりよい設計を示す必要があった。
設計の方向性は次の通りである。
- (a) 2つのSystemを統合し、1つのSystemとして設計する
- (b) ADPを満たすために、Master Dataの作成を行い、Master Dataによる識別、名寄せを行うSystemとする
それぞれの理由を次に示す。
(a) Systemの統合について
ADPを満たすための最も簡単な方法は2つのSystemを統合することである。 今回の場合は、Systemが扱っている問題が本質的に不可分であることからも、1つのSystemとして設計されるべきであることが分かる。
このSystemが扱う問題は抽象的には次の2つである。
- Dataの識別、名寄せ
- Master Dataの生成、提供
名寄せについて考えると、Wikipediaの名寄せの説明によれば、
名寄せ(なよせ)とは、金融機関において、複数口座を開設している顧客の預金額を1つにとりまとめる業務のこと。転じて、金融機関や預金額に限らないデータのとりまとめ全般を指す場合もある。
である。 言い換えれば、名寄せとは次の2つの処理であるとみなせる。
- Dataを識別し一意なIDで特徴づける
- 特徴づけたIDを用いてDataを統合、集約する
上の例で言えば、口座が同じ顧客のものであるかを識別し、それらを1つの口座にまとめるということで、Sansanでは同じ名刺であるか、同じ企業であるかを判別しそれらをまとめる行為となる。 Master Dataの作成とは、dataを企業や事業所といった一意な特徴づけを行い、それらを一元化することである。
Master Dataの作成とは
- 複数のData SourceからDataを収集する
- 収集したDataを、分類し一意なIDを付与する
- 付与したIDを用いてDataを統合、集約する
識別、名寄せとは
- 複数の顧客Dataを収集する
- 収集したDataを識別し、IDを付与する
- 識別のIDを用いてDataを統合、集約する
であって、本質的に同じ問題を異なる対象に行っているにすぎない。 これらは、入力と出力の違いであって、Systemとして1つの振る舞いの元に提供されるべきである。
(b) ADPの解決について
Systemを統合したとしても順序の問題が残る。 本質的にADPを満たすためには、鶏が先か卵が先かの問題を解決する必要がある。
名寄せというのは同一らしいDataを1つにまとめ上げるものであったが、そのためには背後にまとめあげる先が必要である。 このまとめる先がMaster Dataと異なることは、Master Dataとしての一意性に矛盾する。 実際、Master Dataとして提供するDataと識別の結果の矛盾とその調整が、識別率や識別精度が上がらない根本的な原因であった。
この事実は、Rulebaseでやるか、Machine LearningやAIを使うかなど、どのように識別するかによらない。 AIやMachine Learningを用いて識別を行う場合でも、教師となるDataが必要であって、それらはMaster Dataと同等でなければならない。
上の事実を踏まえれば、まず
Master Dataの作成 → Master Dataを用いた識別、名寄せ
というのが正しい順序であることがわかる。 残る問題は、Master Dataをどう作るかということである。 簡単のため、法人の識別だけについて考えれば、日本における法人等は 会社法 等の公的な法律や慣習等により多くの場合客観的にその存在を確認できる。 日本の法人等に限定すれば、例えば会社の場合は 商業登記法 により、会社法人等番号が付与され、 行政手続における特定の個人を識別するための番号の利用等に関する法律 により、法人番号が付与される。 顧客が必要とする法人情報に限定すれば、これらの法人番号が存在するような公的なDataのみを対象にすることができ、Master Dataの収集時に法人番号がKeyになるように収集すれば良い。 顧客がどう入力するかはControlできないが、自社の収集に関しては必要なData ModelとContractの元に収集することは可能なので、Cyclic dependenciesは発生しない。
以上をまとめると、識別、名寄せというのはMaster DataのApplicationの1つにすぎず、Master Dataを主としたServiceがSystemとして目指すべき姿である。
Master Data as a ServiceのData Model
Domainの整理はできたが、作り替えるSystemが同等の機能しか持たないのでは、作り替える意義がない。 企業、事業所、人物をMaster Dataの作成から識別、名寄せまで行うSystemに必要な機能を考える。
一般的なMaster Data Management(MDM)は今時点の企業や事業所の情報を保持し提供する。 しかし、顧客が持つ名刺や企業の情報は必ずしも現在のものとは限らない。 時間変化に対応したMaster Dataを提供する必要がある。
また、名寄せにおいて、企業は合併や買収などによって、統合、廃止されることがあり、過去の社名を新たな社名に統合、廃止することが必要である。
これらの時間方向の変化をDataとして表現し、柔軟に使えるModelとしてGraph Modelを採用した。 詳細はAppendixに譲るが、名寄せとは集合論的にはEquivalence Classを求めることであり、Graph的に表現することが自然である。
次の例を考える。
株式会社A物産
株式会社A物産が、2025-01-01に社名を変更し、株式会社A商事になる
株式会社B商事
株式会社B商社が、2024-01-01に本社移転をし、住所が福岡県福岡市博多区中洲3-7-24から東京都渋谷区桜丘町1-1に変更になる株式会社B商社が、2026-01-02に電話番号を変更し、電話番号が0120-0000-000Bから0120-0000-00BBに変更になる
合併
株式会社A商事が、2026-01-01に株式会社B商社と吸収合併される。
これを時間変化を含むGraphとして次のように表現する。

このとき、1つのTreeができる。 このTreeは、合併、社名変更、本社移転などの変化を同一視する1つのGroupになり、名寄せとはこのGraph上のTreeに属するかの判定問題になる。
この時間変化を考慮したGraph Modelを用いれば、企業の属性情報の変化や、名寄せの問題を自然に表現できる。
設計
Domain及び機能に必要なData Modelの整理ができ、Systemを作り直すのに必要な準備ができた。 しかし、作り直す対象のSystemは会社全体で使われており、Stakeholderは多岐にわたる。 新しく作るSystemが既存のSystemと同等以上の機能を持ち、かつ将来にわたって拡張可能であることを示すために、 Design Doc を書くことにした。
以下は実際に作成したDesign Docで、17ページにわたる。 他にもClient向けにAPIやDomain改修の合理性の資料は別途用意したが、設計上必要な部分だけまとめたものになっている。

System設計について一部抜粋すると、Architectureは次のようになっている。

それぞれのToolについての選定理由などを補足すると、
- Full-text SearchなどMaster Dataを提供する上で、検索機能なども提供できる
- Spanner Graphを用いて、時間変化を含むGraph Modelを表現することができる
- GlobalにScaleすることが実践的に証明されている
- BatchとStreamingを透過的に行え、Apache FlinkやDataflowなど特定のSoftwareに依存せずに記述できる
- Master Dataの集計などのPre-calculationを、Pipeline本体と同一のCodebaseで実現できる
- Golang SDKが存在し、Sansan Data Intelligenceで使われる言語と親和性が高い
Observabilityは OpenTelemetry とGoogle CloudのObservability service(Cloud Monitoring, Cloud Trace, Cloud Logging)を利用している。 Orbitは社内で開発されているGoogle Kubernetes Engine上のWeb Application Platformである。
Design Docは2週間ほどかけて業務の合間に書く必要があったが、その分多くの人のReviewにより、より良いSolutionにすることができた。 Hyrum WrightのSoftware Engineering at Googleにもあるように、Software EngineeringとはTeamでよりよいものを作るということを実感できた。
今後
以上が、MDaaSとしてのSOCv2という新しいSystemを作るに至った経緯と設計の概要です。 SOCv2というMDaaSは無事Releaseできましたが、必要な機能や改善などはまだまだあり、今後も継続的に改善をする必要があります。 SOCv2以外にも、Domainの再整理とSystemの再構成をしたことで、関連するComponentも新たに考える必要が生まれたので、次のようなComponentの開発を進めていく予定です。
- Master Dataの収集を行うためのWeb Crawling Platform
- Master DataのData Quality Management System
- これらのSystemが協調して動くためのContractやAPIの設計
- AIが利用できる形でのMaster Dataの設計
- Sansan Data Intelligence以外のClientが利用できるように移行と機能の拡充
最後にTightなScheduleの中ですがSOCv2をReleaseでき、First ClientとしてSDIもReleaseできたことを大変嬉しく思います。 SDI, SOCv2の開発や設計に関わった方々には大変感謝しています。
カジュアル面談
Sansanでは、中途の方向けにカジュアル面談を実施しています。Sansanでの働き方、仕事の魅力について、現役エンジニアの視点からお話しします。
今回紹介したDesign Docの中身に興味ある方や、Data Quality Management, Crawling Platformなどに興味のある方はカジュアル面談でお話できればと思います。
是非エントリーをご検討ください。
採用説明会イベント
3月31日(火)に採用説明会を行います。
SDIにおけるAI Drivenの開発環境や技術設計などに関する話を行うので、興味ある方は是非参加頂ければと思います。エントリーもお待ちしております。
Appendix
識別、名寄せ、Master Data、正規化の概念の整理をして、集合論的に表現する。
名寄せ、識別とは、比較対象が同一かどうかを比べることである。
同一性の表現は、 Equivalence Relation であり、次の3つの条件を満たす集合とRelationの2つ組 である。
- Reflexive: 任意の
に対して、
- Symmetric: 任意の
に対して、
ならば
- Transitive: 任意の
に対して、
かつ
ならば
このEquivalence Relationの判定を、識別、名寄せと呼び、顧客や要件によって異なるEquivalence Relationを用いるにすぎない。 ML, AIの場合も同等で、Modelによっては確率空間上に表現したものとみなせば同様の議論にできる。
つまるところ、Equivalence Relationが作る同値類の集合が、名寄せ、識別の本質で、同値類としての、Aという集合に入っているものと、Bという集合に入っているものを比較することである。 Data structureとしては、Union Findのようなものを考えてもらえばわかりやすい。
補足として、MLやAIに見られる識別、Matching algorithmの場合は、確率的なModelによる実数へのMappingによって、同値判定に使える構造が、Euclid空間程度の条件を満たすことが多い。 しかし、顧客の体験を考えると、同じ法人のDataに対して同じ名寄せの結果であるDeterministicであることがある種の制約としてあり、住所、社名といった非構造Dataの空間の中で考える必要がある。 この空間の中では、幾何的議論は難しく、代数に閉じた議論が必要になり、 Equivalence Relation程度の構造的仮定で議論をすることが必要となる。 そのRelationの1つの典型的な表現としてGraphはSoftware Engineering観点で扱いやすいData structureとなっている。