5

異なる要素間の連絡先を保存しています。特定のタイプの要素を削除し、削除された要素によって相互接続された要素の新しい接点を保存したいと考えています。

問題の背景

この問題を想像してみてください。他の分子と接触している水分子があります (接触が水素結合の場合、水の周りに他の 4 つの分子が存在する可能性があります)。次の図のように (A、B、C、D は他の原子であり、ドットは接触を意味します)。

 A   B
 |   |
 H   H
  . .
   O
  / \
 H   H
 .   .
 C   D

すべてのドットに関する情報があり、中央の水を除去して、AC、AD、AB、BC、BD、および CD の接触を説明する記録を作成する必要があります。

データベース構造

現在、データベースには次の構造があります。

atoms:

  • "id" integer PRIMARY KEY,
  • "amino" char(3) NOT NULL,(水または他の値の HOH)
  • 原子を識別する他の列

contacts:

  • "acceptor_id" integer NOT NULL,(私の水素に近い原子、ここでは C または D)
  • "donor_id" integer NOT NULL,(ここではAかB)
  • "directness" char(1) NOT NULL,(これは、直接の場合は D、水媒介の場合は W にする必要があります)
  • 距離など、連絡先に関するその他の列

編集:前に示した場合のデータはどのように見えるでしょうか。

atoms:

id|atom|amino
1 | O  | HOH
2 | N  | ARG  <- atom A from image
3 | S  | CYS  <- B 
4 | O  | SER  <- C
5 | N  | ARG  <- D

contacts:

donor_id|acceptor_id|directness
1        4           D
1        5           D
2        1           D
3        1           D

私が作る必要があるものから

contacts:

donor_id|acceptor_id|directness
3        4           W            <- B-C
3        5           W            <- B-D
2        4           W            <- A-C
2        5           W            <- A-D
2        3           X            <- A-B    (These last two rows are escaping me,
4        5           X            <- C-D     there could be also row D-C, but not
                                             both C-D and D-C. A char 'X' could 
                                             be used to mark "no donor/acceptor")

現在のソリューション (不十分)

今、私は持っているすべての連絡先を調べていますdonor.amino = "HOH"。このサンプル ケースでは、C と D から連絡先が選択されます。これらの選択された連絡先のそれぞれについて、現在選択されているacceptor_id連絡先と同じ連絡先を検索します。donor_idこの情報から、新しい連絡先を作成します。最後に、HOH との間のすべての連絡先を削除します。

この方法では、明らかに CD と AB の連絡先を作成できません (他の 4 つは問題ありません)。

同様のアプローチを試してみると、同じdonor_idを持つ2つの連絡先を見つけようとすると、連絡先が重複してしまいます(CDとDC)。

重複することなく 6 つの連絡先すべてを取得する簡単な方法はありますか?

これらの 6 つの必要な行だけを取得する 1 ページの長さの SQL クエリを夢見ています。:-)
ただし、他のアイデアは大歓迎です。

誰がドナーであるかに関する情報を保存することが望ましいですが (可能な場合)、厳密に必要というわけではありません。

この質問をここまで読んでくださった皆様、本当にありがとうございました。

4

2 に答える 2

2

あなたの説明には 1 つの問題があります。

まず、各エッジが接続 X=>Y を表す有向グラフです。ここで、X はドナー、Y はアクセプターです。テーブルatomsは、そのグラフの SQL 表現です。

あなたが望んでいるように見えるのは、方向性のないものです。リンクXYは、XとYが水分子(またはもちろん他の種)を介してリンクされていることを意味しますが、XとYは両方ともドナーまたはアクセプターである可能性があります. このため、最後のテーブルにはあいまいさがあり (注意してください)、一部のリンクがどちらの方向にも発生する可能性があります。それは、列見出しdonor_idacceptor_id最後の列には、あなたが説明した意味がないことを意味しているように思えます。もちろん、これは私の混乱かもしれません。

6 つのリンクすべてを含むテーブルが必要な場合は、それぞれが 1 つの行として表示されますが、ドナー/アクセプターを追跡することについてあまり心配する必要はありません。これは sqlite3 で機能します。

 create temporary view hoh_view as 
 select donor_id as id, atoms.id as hoh_id from contacts, atoms 
       where acceptor_id=atoms.id and atoms.amino='HOH' 
 union select acceptor_id as id, atoms.id as hoh_id from contacts, atoms 
       where donor_id=atoms.id and atoms.amino='HOH';

 select a.id, b.id from hoh_view as a, hoh_view as b 
       where a.id > b.id and a.hoh_id=b.hoh_id;

物事を明確にするために一時的なビューを使用した場所。必要に応じて、各参照を最初のクエリに置き換えることで、これらすべてを 1 つの大きなクエリに入れることができhoh_viewます。私には少し厄介な気がします。整理する方法があるかもしれません。

ドナー/アクセプターの関係を追跡したい場合は、両方のアミノ酸がアクセプターまたはドナーである場合に何をすべきかをどのように決定するかを説明する必要があります (つまり、例の最後の 2 行)。

それがあなたの望みどおりにならない場合は、私が修正できるかもしれません。

于 2010-05-25T19:42:17.793 に答える
1

コメントで例を提供するのは難しいので、回答を投稿することにしました。

元のデータに従わなければならない場合、最初の構造のデータと 2 番目の構造のデータを区別する方法はありません。最初の構造と 2 番目の構造の間の方向を除外するには、追加のグループ化条件が必要です。

sqlite> create table atoms (id INT, atom TEXT, amino TEXT);
sqlite> insert into atoms VALUES (1, 'O', 'HOH');
sqlite> insert into atoms VALUES (2, 'A', 'ARG');
sqlite> insert into atoms VALUES (3, 'B', 'CYS');
sqlite> insert into atoms VALUES (4, 'C', 'SER');
sqlite> insert into atoms VALUES (5, 'D', 'ARG');
sqlite> insert into atoms VALUES (6, 'O1', 'HOH');
sqlite> insert into atoms VALUES (7, 'A1', 'ARG');
sqlite> insert into atoms VALUES (8, 'B1', 'CYS');
sqlite> insert into atoms VALUES (9, 'C1', 'SER');
sqlite> insert into atoms VALUES (10, 'D1', 'ARG');
sqlite> select * from atoms;
1|O|HOH
2|A|ARG
3|B|CYS
4|C|SER
5|D|ARG
6|O1|HOH
7|A1|ARG
8|B1|CYS
9|C1|SER
10|D1|ARG

UPD

元のデータは次のとおりです。

sqlite> .headers ON
sqlite> .mode columns
sqlite> select * from atoms;
id          atom        amino
----------  ----------  ----------
1           O           HOH
2           A           ARG
3           B           CYS
4           C           SER
5           D           ARG
6           O1          HOH
7           A1          ARG
8           B1          CYS
9           C1          SER
10          D1          ARG
sqlite> select * from contacts;
donor_id    acceptor_id  directness
----------  -----------  ----------
1           4            D
1           5            D
2           1            D
3           1            D
6           9            D
6           10           D
7           6            D
8           6            D

クエリは次のとおりです。

select
    c1.donor_id, c2.acceptor_id, 'W' as directness
from
    contacts c1, contacts c2, atoms a
where
    c1.acceptor_id = c2.donor_id
    and c1.acceptor_id=a.id
    and a.amino='HOH'
UNION ALL
select
    c1.donor_id, c2.donor_id, 'X' as directness
from
    contacts c1, contacts c2, atoms a
where
    c1.acceptor_id = c2.acceptor_id
    and c1.acceptor_id=a.id
    and a.amino='HOH'
    and c1.donor_id < c2.donor_id
UNION ALL
select
    c1.acceptor_id, c2.acceptor_id, 'X' as directness
from
    contacts c1, contacts c2, atoms a
where
    c1.donor_id = c2.donor_id
    and c1.donor_id=a.id
    and a.amino='HOH'
    and c1.acceptor_id < c2.acceptor_id;

結果は次のとおりです。

donor_id    acceptor_id  directness
----------  -----------  ----------
2           4            W
2           5            W
3           4            W
3           5            W
7           9            W
7           10           W
8           9            W
8           10           W
2           3            X
7           8            X
4           5            X
9           10           X
于 2010-05-25T21:23:25.490 に答える