Совершенствование данных, хранивших в SQLite - как присоединиться к нескольким контактам?

Я храню контакты между различными элементами. Я хочу устранить элементы определенного типа и сохранить новые контакты элементов, которые были взаимосвязаны устраненным элементом.

Проблемный фон

Вообразите эту проблему. У Вас есть молекула воды, которая находится в контакте с другими молекулами (если контакт является водородной связью, может быть 4 других молекулы вокруг моей воды). Как в следующем изображении (A, B, C, D являются некоторыми другими атомами и точками, означают контакт).

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

У меня есть информация обо всех точках, и я должен устранить воду в центре и создать записи, описывающие контакты A-C, A-D, A-B, B-C, B-D и C-D.

Структура базы данных

В настоящее время у меня есть следующая структура в базе данных:

Таблица 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.

Таким образом, я очевидно не могу создать контакты C-D и A-B (другие 4 в порядке).

Если я пробую аналогичный подход - пытающийся найти два контакта, имеющие тот же donor_id, я заканчиваю с дублирующимися контактами (C-D и D-C).

Существует ли простой способ получить все шесть контактов без дубликатов?

Мне снится кто-то страница долгий SQL-запрос, который получает просто эти шесть требуемых строк.:-)
Однако любые другие идеи приветствуются.

Желательно сохранять информацию о том, кто донор (где возможный), но не строго необходимый.

Большое спасибо всем Вам, кто считал этот вопрос этой точке.

5
задан Krab 25 May 2010 в 20:28
поделиться

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
1
ответ дан 15 December 2019 в 06:18
поделиться

Есть одна трудность с вашим объяснением.

Вы начинаете с ориентированного графа, в котором каждое ребро представляет собой соединение X => Y, где X - донор, а Y - акцептор. Таблица атомов является SQL-представлением этого графа.

Кажется, вам нужно что-то ненаправленное . Таким образом, связь X-Y означает, что X и Y связаны через молекулу воды (или, конечно, некоторые другие разновидности), но что X и Y могут быть как донорами, так и акцепторами. По этой причине ваша последняя таблица имеет двусмысленность (которую вы заметили), так что некоторые ссылки могут появляться в любом случае. Мне кажется, это означает, что заголовки столбцов donor_id и acceptor_id в вашем последнем столбце не имеют никакого значения, которое вы объяснили. Конечно, это может быть мое замешательство.

Если все, что вам нужно, это таблица со всеми 6 ссылками в ней, каждая в виде одной строки, но не беспокойтесь об отслеживании донора / акцептора, тогда это работает для меня в 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;

Где Я использовал временное представление, чтобы прояснить ситуацию. Вы можете объединить все это в один большой запрос, если хотите, заменив каждую ссылку на hoh_view первым запросом. Мне это кажется немного неприятным, и, возможно, есть способ привести его в порядок.

Если вы действительно хотите отслеживать взаимоотношения донор / акцептор, вам необходимо объяснить, как вы решаете, что делать, когда обе аминокислоты являются акцепторами или донорами (т.е. последние две строки в вашем примере).

Если это не дает того, что вы хотите, то, может быть, я смогу исправить это, и это поможет.

2
ответ дан 15 December 2019 в 06:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: