10

質問

これに対する解決策は、オイゲンのビューのアイデアを使用してすぐ下にあることに注意してください!

私は、2 人のユーザーが友達を作ることを可能にする PHP/MySQL ユーザー主導のサイト用のチャット モジュールを作成しており、チャット システムに eJabberd を選択しました。

mod_roster_odbcPHP デーモンを使用して外部認証を正常にセットアップしました。また、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 つの行を使用してフレンドシップを表します。

私の主な質問:

  1. この友情を一列にまとめることができるでしょうか?この非公式ドキュメントからいくつかの組み合わせを試しましたが、成功しませんでした。Pidgin クライアントを使用して XMPP サーバーに接続してテストしています。
  2. 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;
4

1 に答える 1

3

IIUC、テーブルrosteruserseJabberdサーバー アプリの POV から読み取り専用です。viewこれにより、自分の友人テーブルに必要な 1 行から 2 行を作成するに置き換えるのが簡単になります。

あなた自身のフレンドシップ テーブルの構造がわからないので、完全なコードを提供することはできませんが、疑似 SQL として私が考えたのは次のとおりです。

CREATE VIEW rosterusers AS SELECT * FROM (
    SELECT 
        selfuser.name AS username, 
        frienduser.jid AS jid,
        -- ....,
        selfuser.jid AS jid_as_id
    FROM
        users AS selfuser
        INNER JOIN friendships ON ....
        INNER JOIN users AS frienduser ON ...
    UNION SELECT 
        frienduser.name AS username, 
        selfuser.jid AS jid,
        -- ....,
        frienduser.jid AS jid_as_id
    FROM
        users AS selfuser
        INNER JOIN friendships ON ....
        INNER JOIN users AS frienduser ON ...
);

その後

SELECT
    username, jid, subscription, ask, server, type
FROM rosterusers
WHERE jid_as_id='user1@myserver.org'

UNIONビューの各部分から1行ずつ、2行が表示されます

于 2012-07-06T11:05:36.777 に答える