フォロワーを個人ユーザーへマイグレーションする処理を実装した話

こんにちは!開発本部・バックエンドエンジニアのSongです。

2月の下旬に個人ユーザー・フォロワー統合プロジェクトをリリースできました。

このプロジェクトでは以下の機能を提供しています

  • ユーザーが自身の操作でFacebookフォロワーアカウントを個人ユーザーアカウントへマイグレーションできる
  • ユーザーがFacebook認証で個人ユーザーとして新規登録・ログインできる
  • Facebookフォロワーユーザーは新規登録できなくなった。ただし、ログインはできる

最も重要なのはFacebookフォロワーが自身の操作でアカウントを個人ユーザーへマイグレーションできるという機能なので、今回その機能の実装についてお話します。

目次

背景

現在、PR TIMESでは4つのユーザータイプが存在しています

  • 企業ユーザー
  • メディアユーザー
  • 個人ユーザー
  • Facebookフォロワー(以下フォロワーと呼ぶ)

各タイプのユーザーには、それぞれの特別な仕様や機能があります。しかし、フォロワーの機能はほぼ個人ユーザーと同じなので、分かれているメリットや明確な理由がありません。具体的には

  • フォロワーが提供している機能は企業をフォローすること
  • フォローする機能は個人ユーザーにも存在しているため、フォロワーのアカウント情報テーブルとフォローのテーブルをマイグレーションできれば良い

さらに、個人ユーザーアカウントの利便性を向上するために、SNS認証(まずはFacebook)で個人ユーザーとして新規登録・ログイン機能を追加したいのですが、Facebookでログインする機能はフォロワーのログインで利用しているため、個人ユーザーとフォロワーを統合し、個人ユーザーをFacebookでもログインできるようにすることになりました。

最初の段階で、個人ユーザーとフォロワーが統合されるということを事前にフォロワーに告知して、告知期間を経てから、自動的に個人ユーザーにマイグレーションすることにしました。ただし、事前告知期間中にユーザーが自身の操作でマイグレーションすることも可能です。

今回はユーザーが自身の操作でマイグレーションできる機能を中心に説明します。

ユーザーデータを調査した結果

マイグレーションができるように、とりあえずフォロワーと個人ユーザーのデータを調査しました。調査結果は以下のようになりました。

  • フォロワーと個人ユーザーのデータが主に2つのテーブルに保存されている。これらのテーブルもユーザータイプによって別の構造や制約を持っている
    • アカウント情報
    • フォロー中の企業情報(以下フォロー情報と呼ぶ)
個人ユーザーとフォロワーのアカウント情報、フォロー情報のテーブル名
  • 個人ユーザーのアカウント情報テーブルにはメールアドレスにUNIQUE、NOT NULL制約があり、氏名にNOT NULL制約がある(以下個人ユーザーテーブルの制約と呼ぶ)
  • 1つのメールアドレスは企業ユーザー、メディアユーザー、個人ユーザーという3つのユーザータイプにいずれか1つしか登録できない(以下PR TIMESのユーザー制約と呼ぶ)。つまり、企業ユーザー、メディアユーザー、個人ユーザーが同じメールアドレスで存在できない
  • フォロワーのアカウント情報テーブルにはメールアドレスや氏名にNOT NULL制約がない。その上、メールアドレスが他のユーザータイプと重複可能であり、メールアドレスや氏名がないフォロワーも存在している
各ユーザータイプのメールアドレスの制約

どんな問題が発生したのか?

調査結果に沿って、以下の問題が発生しました。

テーブルの構造や制約が違う問題

フォロワーと個人ユーザーテーブルの構築や制約が違うため、データをそのままマイグレーションすることができません。

情報が重複する・欠ける問題

メールアドレス、氏名が欠けているまたはメールアドレスが企業ユーザー、メディアユーザーと重複されるフォロワーアカウントが個人ユーザーへマイグレーションできません。個人ユーザーテーブルの制約PR TIMESユーザーの制約に違反するためです。

問題をどのように解決したのか?

では上記の2つの問題をどのように解決したのか?

テーブルの構造や制約が違う問題

フォロワーアカウントを個人ユーザーアカウントへマイグレーションできるように、個人ユーザーのアカウント情報テーブルとフォロー情報テーブルに新しいカラムや制約の追加で解決できました。

まず、フォロワーのアカウント情報テーブルにFacebookのユーザーIDを保存しているカラムがありますが、個人ユーザの方はないため、追加する必要があります。

ALTER TABLE table_name ADD COLUMN fb_user_id VARCHAR(128);

次に、個人ユーザーのフォロー情報テーブルにはPRIMARY制約がありません。しかし、今後マイグレーションを実装するにあたり、PRIMARY制約がないと情報の重複で実装に困る可能性があります。そのため、追加する必要があります。

このテーブルには主にユーザーIDと企業IDを保存するため、2つのカラムを合わせてPRIMARY制約を追加しました。

ALTER TABLE table_name ADD CONSTRAINT table_name_pkey PRIMARY KEY (user_id, company_id);

さらに、フォロー情報テーブルのレコード数が増えてもパフォーマンスの問題が出ないように、これまでなかったcompany_idのINDEXも追加しました。

CREATE INDEX table_name_company_id_idx ON table_name (company_id);

情報が重複する・欠ける問題

調査結果によって、フォロワーを4つのパターンに分けました。

パターン①:メールアドレスが個人ユーザーと重複しているフォロワー

フォロワーアカウントのメールアドレスに該当する個人ユーザーアカウントが既に存在するため、ユーザーがそのままアカウントマイグレーションを実行できます。

その上、マイグレーションする際に個人ユーザーの情報が優先されるため、氏名が欠ける問題も解決できます。

パターン②:メールアドレスまたは氏名がないフォロワー

フォロワーアカウントのメールアドレスまたは氏名がないため、個人ユーザーテーブルの制約に違反してしまいます。

アカウントマイグレーションできるように、ユーザーが情報を追加する必要があります。

パターン③:メールアドレスが企業ユーザーまたはメディアユーザーと重複しているフォロワー

メールアドレスが企業ユーザーまたはメディアユーザーと重複しているため、PR TIMESユーザーの制約に違反してしまいます。

アカウントマイグレーションできるように、ユーザーが別のメールを追加する必要があります。もちろん、もし氏名がないなら追加する必要があります。

パターン④:メールアドレスや氏名があり、メールアドレスが他のユーザータイプと重複していないフォロワー

情報があり、個人ユーザーテーブルの制約PR TIMESのユーザー制約に違反していないため、ユーザーがそのままアカウントマイグレーションを実行できます。

アカウントマイグレーションの処理

ではマイグレーションを実行する時にどのように処理すれば良いでしょうか?

今回はフォロワーのアカウント情報テーブルとフォロー情報テーブルをマイグレーションする必要があります。上記の4つのパターンがあるので、アカウント移行アカウント統合という2つの処理に分けました。

アカウント移行

フォロワーアカウントの情報を個人ユーザーアカウントに移行するという処理です。

技術的には個人ユーザーのテーブルに新しいデータをINSERTする処理です。該当の個人ユーザーが存在していないためです。もちろん情報が欠ける場合、移行できるようにユーザーが情報を追加する必要があります。

アカウント移行の対象はユーザーパターン②、③、④です。

アカウント統合

フォロワーアカウントの情報を個人ユーザーアカウントに統合するという処理です。

技術的には、個人ユーザーのテーブルをフォロワーの情報でUPDATEすることです。同じメールアドレスでフォロワーと個人ユーザーに登録したため、統合先が既に存在しています。ですから、INSERTの代わりに、UPDATEで処理します。

ただし、フォロー情報はUPDATEではなくUPSERTで処理します。なぜならフォロワーのフォロー情報を統合する際に、個人ユーザーのフォロー情報テーブルに該当するレコードが存在すればUPDATEで処理するが、存在しなければINSERTで新しいレコードを追加する必要があるからです。

アカウント統合の対象はユーザーパターン①のみです。

フォロワーの管理画面上でアカウント移行・統合を行う

今回のアカウント移行・統合の処理はユーザーの管理画面で行われます。

では、フォロワーがログインした後、そのアカウント移行と統合とどちらが実行できるか?

情報が欠けることをどうやって判定できるか?を考える必要があります。

ログイン中のフォロワーのメールアドレスと氏名を判定することに沿って、以下のように分岐処理で実装しました。

フォロワーの管理画面上にアカウント移行・統合を行う分岐処理

分岐処理が多いですが、以下のようにまとめられます

  • ログイン中のユーザーがアカウント移行・統合の条件を満たすとしたら、管理画面上に該当のモーダルやお知らせが表示される
  • ユーザーがそのモーダルやお知らせにあるリンクをクリックすると、アカウント移行・統合を確認できる。もちろん情報が欠けたら確認前に入力する必要がある
  • ユーザーが確認した後、アカウント移行・統合が実行され、終了する

個人ユーザーの管理画面上でアカウント統合を行う

個人ユーザーとフォロワー両方登録している方も個人ユーザーにログインしてからアカウント統合を実行できます。

個人ユーザーのメールアドレスに該当するフォロワーが存在するかという条件を判定するだけなので、処理がとても簡単です。

個人ユーザーの管理画面上にアカウント統合を行う分岐処理

最後に

今回のプロジェクトの実装で、フォロワーユーザーと個人ユーザーが自身の操作でアカウントをマイグレーションすることができました。

テーブルの調整やアカウント移行・統合の分岐処理のおかげで、告知期間を経てから、自動的にフォロワーアカウントを個人ユーザーにマイグレーションすることが安易に実装できると思います。

この記事を書いた人

株式会社PR TIMES 開発本部 バックエンドエンジニア

目次
閉じる