質問
これに対する解決策は、オイゲンのビューのアイデアを使用してすぐ下にあることに注意してください!
私は、2 人のユーザーが友達を作ることを可能にする PHP/MySQL ユーザー主導のサイト用のチャット モジュールを作成しており、チャット システムに eJabberd を選択しました。
mod_roster_odbc
PHP デーモンを使用して外部認証を正常にセットアップしました。また、MySQLrosterusers
テーブルを手動で使用してデータを入力することで、eJabberd にフレンドシップを取得することに成功しました。掘り下げた結果、この特定のコメントは、チャット モジュールのフレンド リストでその友情を表すために、各列を何に設定すればよいかを知るのに非常に役立つことがわかりました。
rosterusers
友情を処理するための私の現在の方法は、テーブルに 2 つの行を挿入することです。
# Relationship user1 => user2
INSERT INTO rosterusers (username, jid, subscription, ask, server, type)
VALUES ('user1', 'user2@myserver.org', 'B', 'N', 'B', 'item');
# Relationship user2 => user1
INSERT INTO rosterusers (username, jid, subscription, ask, server, type)
VALUES ('user2', 'user1@myserver.org', 'B', 'N', 'B', 'item');
相互の友情には2行が必要なので、これにはあまり満足していません.
XMPP では、標準でユーザー間のシングル リンクとデュアル リンクが許可されることを理解しています。私の質問の性質から推測できるように、私自身のアプリケーションのフレンド システムは、1 つの行を使用してフレンドシップを表します。
私の主な質問:
- この友情を一列にまとめることができるでしょうか?この非公式ドキュメントからいくつかの組み合わせを試しましたが、成功しませんでした。Pidgin クライアントを使用して XMPP サーバーに接続してテストしています。
- 2 つのデータベース (フレンドと XMPP 名簿) の同期を維持する最善の方法は何ですか?
TRIGGER
今のところ、MySQLが最もクリーンなオプションかもしれないと思います。
そうでない場合は、テーブルを変更して、それrosterusers
が自分のアプリケーションのフレンド行を参照するように取得し、それがクロス データベースの外部キーのように機能するようにすることもできます。
ソリューション コード
Eugenが提案したように、ビューを作成しました。コードは最も洗練されたものではありませんが、テストしたところ、MySQL 5.5 上の eJabberd 2.1 で動作します。
私の正確なセットアップでは 2 つのデータベースを使用するため、. を使用してメイン アプリケーションのデータベースを明示的に参照していますmain_database.table_name
。
コードは 2 つのクエリの結合です。最初のクエリは User、Friend を取得し、2 番目のクエリは Friend、User を挿入します。私はUNION ALL
スピードと「重複」を通過させるために使用しています。
アプリケーションを変更する必要がなく、すぐに更新されるため、これは問題を処理するための非常に優れた方法だと思います。
CREATE VIEW rosterusers AS
SELECT LCASE(ua1.Username) AS `username`, CONCAT(LCASE(ua2.Username), '@myserver.org') AS `jid`,
'B' AS `subscription`,
'N' AS `ask`,
'N' AS `server`,
'item' AS `type`,
'B' AS `subscribe`,
d1.Created AS `created_at`,
ua2.Username AS `nick`,
'' AS `askmessage`
FROM main_database.User_Friend AS `d1`
INNER JOIN main_database.User AS `ua1` ON `d1`.UserID = `ua1`.ID
INNER JOIN main_database.User AS `ua2` ON `d1`.FriendID = `ua2`.ID
WHERE d1.IsApproved = 1
UNION ALL
SELECT LCASE(ub2.Username) AS `username`, CONCAT(LCASE(ub1.Username), '@myserver.org') AS `jid`,
'B' AS `subscription`,
'N' AS `ask`,
'N' AS `server`,
'item' AS `type`,
'B' AS `subscribe`,
d2.Created AS `created_at`,
ub1.Username AS `nick`,
'' AS `askmessage`
FROM main_database.User_Friend AS `d2`
INNER JOIN main_database.User AS `ub1` ON `d2`.UserID = `ub1`.ID
INNER JOIN main_database.User AS `ub2` ON `d2`.FriendID = `ub2`.ID
WHERE d2.IsApproved = 1;