DataflowsでExcelや基幹システムのデータをDataverseに定期同期するとき、突合キーに何を使うかで設計の安全性が決まる。
結論を先に言う。DataverseのデフォルトName列は突合キーに使ってはいけない。 使うたびに同名他社・表記ゆれ・社名変更の3トラップが確実に発動する。
解法は、基幹システム側で一意管理されている業務コード列(代理店コード・顧客IDなど)を専用に用意し、代替キー(Alternate Key)として設定することだ。
Name列をVLOOKUPのキーにしてしまう典型ミス
ExcelのVLOOKUPを長く使ってきた人ほど、DataverseのName列を自然な突合キーとして使いたくなる。「会社名が一致したら同じレコード」という感覚は、スプレッドシートの世界では合理的だ。
Dataverseの画面を開くと、Name列が最も目につく場所にある。Dataflowsのフィールドマッピング設定でもName列は真っ先に候補に上がる。だから直感的に選んでしまう。
ただし、DataverseのName列は「人間がアプリ画面で見るためのラベル」として設計されている。Microsoft Learnの公式ドキュメント(Work with alternate keys、2026年3月更新)が代替キーの設計思想として示している通り、データベース上の一意性保証はName列の責務ではない。突合キーに使うと、以下の3つのトラップが確実に発動する。
3つのトラップ:同名他社・表記ゆれ・社名変更
トラップ1:同名他社(重複・誤上書き)
異なる企業が同じ名称を持つケースは珍しくない。「山田商事」「東西商事」のような名前は地域をまたげば複数存在する。Name列で突合すると、別の会社のレコードが上書きされる。気づいたときには、どちらが正しいレコードか判断できない状態になっている。
トラップ2:表記ゆれ(別レコード扱い)
「株式会社〇〇」「(株)〇〇」「㈱〇〇」は、人間には同じ会社に見える。Dataverseは文字列として比較するため、すべて別のレコードとして追加し続ける。定期同期のたびにレコードが増殖する。
トラップ3:社名変更(突合機能不全)
社名変更が起きると、Excelや基幹システム側の名称が更新される。Name列を突合キーにしていると、変更後の名称がDataverse上に見つからず、既存レコードの更新ではなく新規レコードの作成として処理される。過去の取引履歴との紐付けが切断される。
3つとも、「いつか起きるかもしれないリスク」ではない。データが蓄積されるほど確実に発動する構造的な問題だ。
設計の判断軸:「人間が見るデータ」と「システムが判別するデータ」を切り離す
データベース設計の基本原則として、「人間が見るデータ」と「システムが判別するデータ」は別の列に持つ。Name列は前者に属する。突合キーには後者が必要だ。
具体的には、基幹システム側で一意管理されている業務コード列を使う。代理店コード・顧客番号・取引先ID——企業が社名を変えても、コードは変わらない。同名の別企業が存在しても、コードは異なる。表記ゆれは最初から発生しない。
この業務コード列をDataverseに専用列として追加し、代替キー(Alternate Key)として登録することで、DataverseがこのコードをName列と並ぶ「第2の主キー」として扱えるようになる。Dataflowsはその列を使ってUpsert(既存行の更新 + 新規行の追加)を安全に実行できる。
代替キーの仕様と制約(設定前に確認する数値)
代替キーを設定する前に、以下の制約を把握しておく。数値はすべてMicrosoft Learnの公式ドキュメント(Work with alternate keys、2026年3月更新)からの直接引用だ。
| 制約項目 | 上限値 |
|---|---|
| テーブルあたりの代替キー数 | 最大10個 |
| 1キーあたりの列数(複合キー) | 最大16列 |
| キーサイズの合計 | 900バイト以下(SQLインデックス制約準拠) |
加えて、以下の列は代替キーとして設定できない(Define alternate keys to reference rows、2025年8月更新):
- 列セキュリティが有効な列:設定不可
- NULL値を含む列:一意性が強制されない(重複レコードのリスクがある)
- 仮想テーブルの列:代替キー非対応(外部システム側の一意性を強制できないため)
もう一つ注意点がある。代替キーとして設定する列の値に特殊文字( /,<,>,*,%,&,:,\,? )が含まれると、GET/PATCH(Upsert)操作が機能しなくなる。 業務コードに記号を使っている場合は事前に確認が必要だ。
サポートされるデータ型は6種(Decimal Number・Whole Number・Single line of text・Date Time・Lookup・Option Set)。業務コード列に推奨するのは**Single line of text(1行テキスト)**で、英数字IDであれば問題なく使える。
代替キーの設定手順3ステップ
設定はPower Appsのメーカーポータルから行う(Define alternate keys using Power Apps、2025年5月更新)。
ステップ1:業務コード列を作成する
対象テーブルに新しい列を追加する。データ型は「Single line of text(テキスト)」を選択。列のプロパティで「必須(Required)」に設定しておく。NULL値が入ると一意性が保証されないため、必須設定は省略しない。
列名の例:agency_code(代理店コード)、customer_id(顧客ID)
ステップ2:Keysメニューから代替キーを新規作成する
Power Appsポータルで対象テーブルを開き、左側のメニューから「Keys」を選択する。「+ New Key」をクリックし、キーの名前と対象列(ステップ1で作成した業務コード列)を指定して保存する。複数列の組み合わせで一意性を保つ場合は複合キーとして設定できるが、単一の業務コード列であれば1列の指定で十分だ。
ステップ3:Activeステータスを確認する
保存直後はステータスが「Pending」になる。バックグラウンドでインデックスが作成され、完了すると「Active」に変わる。所要時間は既存レコード数と環境負荷によるため数秒〜数分かかる場合がある(公式ドキュメントに具体的な時間の記載はない)。
ステータスの遷移は Pending → In Progress → Active の順で進む。「System job」の名称は「Create index for {キー名} for table {テーブル名}」の形式で確認できる。ジョブ完了後はリンクが画面から自動消去される。
Failedになる主な原因は2つ:既存レコードに重複値が存在する場合、またはキーサイズが900バイト制約を超過している場合だ。Failedが表示されたら、既存データの重複チェックとキーサイズの見直しから始める。
DataflowsでのUpsert:代替キーの指定がスイッチになる
代替キーの設定が完了したら、Dataflowsのフィールドマッピング設定に戻る。
Dataflowsではフィールドマッピングの設定画面で「キーフィールド(Key field)」を指定できる。ここに代替キーとして設定したコード列を指定することで、Upsertが有効化される(Field mapping considerations for standard dataflows)。
| キーフィールドの設定 | Dataflowsの動作 |
|---|---|
| 代替キーを指定 | Upsert:既存レコードは更新、新規は追加 |
| 未指定 | 常に新規作成のみ(重複が蓄積する) |
動作の仕組みはシンプルだ。Dataflowsがデータを書き込むとき、指定したキーフィールドの値でDataverse上の既存レコードを検索する。一致するレコードがあれば更新(Update)、なければ追加(Insert)を行う。これがUpsertの正体だ(Use Upsert to Create or Update a Record in Dataverse)。
一点注意:DataflowsのUI上でキーとして選択できる列のデータ型について、Text型・Number型は確実に機能する。Lookup型・Choice型がDataflowsのキー設定画面で選択可能かどうかは実機確認を推奨する(コミュニティ情報あり、公式確認は取れていない)。
まとめ
DataverseのName列は「人間がアプリで見るためのラベル」であり、突合キーではない。突合キーには、基幹システム側で一意管理された業務コード列を用意し、代替キーとして設定する。この分離が、DataflowsのUpsertを安全に動かす設計の核心だ。
設定の流れを3行でまとめると:
- 業務コード列をテキスト型・必須で追加する
- Keysメニューで代替キーを作成し、コード列を指定する
- Activeになったことを確認して、Dataflowsのキーフィールドにこのキーをマップする
次の一歩:M365 Developer Tenantを持っているなら、空のテーブルに代替キーを設定してDataflowsからUpsertを1回実行してみる。既存レコードが更新されることを目視確認できれば、設計の感覚がつかめる。
→ 関連記事:Power PlatformでDataverseにデータを取り込む構成パターン
このシリーズの関連記事: