2

私は個人的なメッセージのために次の表を持っています:

id*    sender*    recipient* del_by_rec del_by_send
-+----------+-------------+-----------+-----------+
 2     tom        beth            0          1
 5     tom        josh            0          1
 5     tom        chris           1          1
 7     ashley     burt            1          0
 8     jenna      tom             1          0
 8     jenna      ashley          0          0
 8     jenna      jenna           1          0
10     ashley     burt            0          0

どこ

  • idメッセージIDです。
  • senderrecipientはユーザーログインです、
  • senderメッセージに固有ですid
  • recipientメッセージには複数存在する可能性がありますid
  • del_by_rec受信者が受信トレイからメッセージを削除した場合は1であり、
  • del_by_send送信者が送信トレイからメッセージを削除した場合は1です。
  • id---は主キーでありsenderrecipient
  • ididメッセージを含む別のテーブルの主キーを参照します。

現在のユーザーが削除することを決定したら、メッセージをテーブルから安全に削除できるかどうかを判断する必要があります。

受信者の受信トレイから

  1. 送信者がすでに送信トレイからメッセージを削除している場合(del_by_send= 1); と
  2. このユーザーが受信トレイからこのメッセージをまだ削除していない唯一の受信者である場合(このユーザーの場合はdel_by_rec= 0、del_by_rec他のすべての受信者の場合は= 1)。

または送信者の送信トレイから

  1. すべての受信者がこのメッセージを受信ボックスから削除した場合(del_by_rec=このメッセージのすべての受信者に対して1)。

del_by_recそれ以外の場合、現在のユーザーは、対応するフラグまたはdel_by_sendフラグを1に設定することにより、このメッセージに削除のフラグを立てます。

この基準を効率的に照会する方法はありますか

  1. 現在のメッセージを表示している現在のユーザー。また
  2. 現在のユーザーが複数のメッセージを大量に削除しています(この場合、複数行の結果が返されると思います)。

boolean/intが返されるのは素晴らしいことです。

私の愛のために、私はこのクエリを通り抜けることができませんでした(ユーザーがでashleyあり、彼女が受信トレイからメッセージを削除したいと仮定します8):

SELECT (
    (SUM(del_by_send) > 0) # sender has deleted (at least 1)
    && ((SUM(del_by_rec) + 1) >= COUNT(id)) # only 1 recipient has not deleted yet
    && ((SELECT del_by_rec FROM msg_meta WHERE recipient = 'ashley' AND id = 8) = 0) # and that recipient is this user
)
FROM msg_meta
WHERE id = 8
GROUP BY id
  1. これでうまくいくようですが、ちょっとやり過ぎですか?
  2. id高価なを避けるために、これは複数のメッセージに対して失敗しますforeachWHERE id IN (7,10)受信者を試しましburtたが、サブクエリにうまく組み込むことができませんでした。

ヘルプ。ありがとうございます。

4

3 に答える 3

1

アイデア1:
ブール値を反転し(列をkeepまたはsaveのように呼び出します)、最初にユーザーの削除を更新してから実行します:

SELECT id , SUM(del_by_send) + SUM(del_by_rec)
FROM msg_meta
WHERE id = 8
GROUP BY id

2番目の列が0のレコードはすべて削除可能です。

アイデア2:
2つのステップで、サブクエリを使用して実行できます(1つのIDで実行可能ですが、多くの場合は低速になる可能性があります)
ステップ1:1つまたは複数の削除(recまたは送信)のフラグを更新しますメッセージID。
ステップ2 :

SELECT id 
FROM msg_meta t
WHERE t.id = 8
AND NOT EXISTS(
  SELECT id
  FROM msg_meta t2
  WHERE t.id = t2.id
  AND (t2.del_by_rec = 0 OR t2.del_by_sent = 0)
)

たぶん、これらのうちの1つは、あなたが必要とするアイデアまたはアイデア3の火付け役を与えるかもしれません;)

于 2012-08-09T11:36:01.523 に答える
1

私の提案は、サブクエリを使用して、メッセージレベルで必要な情報を取得し、これにロジックを適用することです。次のクエリが近づいています。

select id, (case when sum_del_by_send > 0 and (num_rec - sum_del_by_rec) <= 1
                 then 'Y'
                 else 'N'
            end) as IsSafeToDelete
from (select id,
             sum(del_by_send) as sum_del_by_send,
             sum(del_by_rec) as sum_del_by_rec,
             count(*) as num_rec
      from msg_meta
      group by id
     ) m

これは、現在の受信者を考慮していません。このバリアントは次のことを行います。

select id, (case when sum_del_by_send > 0 and (num_others - sum_del_by_others) = 1
                 then 'Y'
                 else 'N'
            end) as IsSafeToDelete
from (select id,
             sum(del_by_send) as sum_del_by_send,
             sum(case when recipient <> @RECIPIENT then del_by_rec end) as sum_del_by_others,
             sum(case when recipient <> @RECIPIENT then 1 else 0 end) as num_others,
             count(*) as num_rec
      from msg_meta
      group by id
     ) m

これにより、すべてのメッセージが一度に処理されます。特定のメッセージIDを処理するには、サブクエリの「groupbyid」を次のように置き換えます。

where id = @ID

(@RECIPIENTと@IDは、クエリをカスタマイズする値を意味します。)

于 2012-08-09T14:07:53.823 に答える
0

なんとよく文書化された投稿...(私はそれらがすべてあなたのもののようだったと思いました。)...

メッセージごとに送信者は1人しかいないことがわかります...では、送信者のログインとメッセージテーブルのdel_by_sendフラグを入力しないのはなぜですか?

これにより、送信者がメッセージを削除することを決定したときに1行だけを更新する時間を大幅に節約できます。各メッセージの送信者名を1回だけ記録することで、多くのスペースを確保できます。

テーブルが軽くなり、更新が1行を超えて変更されることはないため、これによりすでに処理速度が向上するはずです。

(これは、正規化標準で推奨されているものに近いでしょう。データベースの正規化の詳細については、http://en.wikipedia.org/wiki/Database_normalizationを確認してください)

安全な削除へのあなたの探求を単純化するために、私はメッセージテーブルにメッセージに関係した人々の数を記録します。(たとえば、メッセージID 5の場合、people_countは3(Tom、Josh、Chris)になります。ユーザー(送信者または受信者)がメッセージを削除するたびに、このカウンターをデクリメントします。カウンターが0になったら、安全に削除できます。メッセージ。

このヒープを願っています...

于 2012-08-09T12:06:10.773 に答える