Перейти к содержанию
Форум химиков на XuMuK.ru
β

Модель данных для хранения и обработки химической информации


silentlyinmay

Рекомендуемые сообщения

🚑 Решение задач, контроши, рефераты, курсовые и другое! Онлайн сервис помощи учащимся. Цены в 2-3 раза ниже! 200 руб. на 1-й заказ по коду vsesdal143982

Доброго времени суток всем!

 

Решил поделится небольшим наблюдением и размышлениями. Возможно кому-то будет полезно или кто то  подскажет более изящный подход

 

Занимаюсь автоматизацией обработки данных или говоря более официально выполняю обязанности data engineer.  

На вход поступают таблицы - exсel или ods с данными субстанций - что с чем смешано, в какой концентрации, свойства - плотность, цвет, запах или результаты операций - смешали X + Y получили Z, выпал ли осадок, если да то какой

Моя задача, данные собирать в одном хранилище - "озере данных" и предоставлять доступ разработчикам ПО.

Первоначально в качестве места хранения данных была выбрана mariadb - реляционная база данных.

С одной стороны экспорт таблиц excel в неё особых проблем не вызывает - создаёшь новую таблицу с нужными столбцами и load data.  С другой стороны результат получается весьма далёким как от реляционной модели так и от возможности удобной работы при помощи sql.  Нормальные формы не выполняются. Кроме первой конечно. Таблиц очень много и они  между собой логически не связанны.  Нормально обращаться к этой свалки данных не выходит.

 

На мой взгляд использование таблиц - excel или аналогов и даже реляционных баз данных для ведения химических записей совершенно нерационально.

 

Рациональный подход - json.  Это весьма простой язык разметки, популярный в ИТ но увы малопонятный и даже пугающий людей в лаборатории и на производстве.

 

В качестве доказательств того что не так страшен чёрт как его малюют несколько примеров.

Рабочие данные обсуждать не могу поэтому вся возня будет с данными из проекта https://github.com/Bowserinator/Periodic-Table-JSON  - таблица Менделеева

 

Потребуется linux компьютер с доступом в интернет + git + jq + postgresql - всё в штатной поставке linux, бесплатно и пр

 

Клонируем репу себе на комп:

 

git https://github.com/Bowserinator/Periodic-Table-JSON

 

cd Periodic-Table-JSON

 

Выведем информацию о элементе с номером 2 (нумерация элементов массива идёт с 0, поэтому 2 превращается в 1):

 

[user@host Periodic-Table-JSON]$ cat ~/Общедоступные/Periodic-Table-JSON/PeriodicTableJSON.json |jq ' .elements[1]'
{
  "name": "Helium",
  "appearance": "colorless gas, exhibiting a red-orange glow when placed in a high-voltage electric field",
  "atomic_mass": 4.0026022,
  "boil": 4.222,
  "category": "noble gas",
  "density": 0.1786,
  "discovered_by": "Pierre Janssen",
  "melt": 0.95,
  "molar_heat": null,
  "named_by": null,
  "number": 2,
  "period": 1,
  "group": 18,
  "phase": "Gas",
  "source": "https://en.wikipedia.org/wiki/Helium",
  "bohr_model_image": "https://storage.googleapis.com/search-ar-edu/periodic-table/element_002_helium/element_002_helium_srp_th.png",
  "bohr_model_3d": "https://storage.googleapis.com/search-ar-edu/periodic-table/element_002_helium/element_002_helium.glb",
  "spectral_img": "https://en.wikipedia.org/wiki/File:Helium_spectrum.jpg",
  "summary": "Helium is a chemical element with symbol He and atomic number 2. It is a colorless, odorless, tasteless, non-toxic, inert, monatomic gas that heads the noble gas group in the periodic table. Its boiling and melting points are the lowest among all the elements.",
  "symbol": "He",
  "xpos": 18,
  "ypos": 1,
  "wxpos": 32,
  "wypos": 1,
  "shells": [
    2
  ],
  "electron_configuration": "1s2",
  "electron_configuration_semantic": "1s2",
  "electron_affinity": -48,
  "electronegativity_pauling": null,
  "ionization_energies": [
    2372.3,
    5250.5
  ],
  "cpk-hex": "d9ffff",
  "image": {
    "title": "Vial of glowing ultrapure helium. Original size in cm: 1 x 5",
    "url": "https://upload.wikimedia.org/wikipedia/commons/0/00/Helium-glow.jpg",
    "attribution": "Jurii, CC BY 3.0 , via Wikimedia Commons, source: https://images-of-elements.com/helium.php"
  },
  "block": "s"
}
[user@host Periodic-Table-JSON]$

 

Выведем отдельные значения - имена элементов 2-го и 23-го:

 

[user@host Periodic-Table-JSON]$ cat ~/Общедоступные/Periodic-Table-JSON/PeriodicTableJSON.json |jq ' .elements[1,22] | .name'
"Helium"
"Vanadium"
[user@host Periodic-Table-JSON]$

 

Выведем список всех ключей которые есть в элементе описывающем 1-ый элемент таблицы Менделеева:

 

[user@host Periodic-Table-JSON]$ cat ~/Общедоступные/Periodic-Table-JSON/PeriodicTableJSON.json |jq '.elements[0] | keys'
[
  "appearance",
  "atomic_mass",
  "block",
  "bohr_model_3d",
  "bohr_model_image",
  "boil",
  "category",
  "cpk-hex",
  "density",
  "discovered_by",
  "electron_affinity",
  "electron_configuration",
  "electron_configuration_semantic",
  "electronegativity_pauling",
  "group",
  "image",
  "ionization_energies",
  "melt",
  "molar_heat",
  "name",
  "named_by",
  "number",
  "period",
  "phase",
  "shells",
  "source",
  "spectral_img",
  "summary",
  "symbol",
  "wxpos",
  "wypos",
  "xpos",
  "ypos"
]
[user@host Periodic-Table-JSON]$

 

 

Вот примерно так при помощи кувалды и какой-то матери, шучу - простейших утилит. Без навыков написания кода можно извлекать информацию из json

 

Помимо jq существуют бесплатные утилиты позволяющие создавать json документы,  печатать их в красивом виде.  json можно использовать и внутри postgresql,  притом бесплатно  или в специальной БД,  например в MongoDB.

 

 

 

 

 

 

Изменено пользователем silentlyinmay
Ссылка на комментарий

А чем облегчится работа с беспорядочными данными? Если вы для беспорядочных данных сделаете нормальные названия колонок - получите такую же таблицу из которой можно выбирать нужные данные любым языком запросов.

Ссылка на комментарий

Попробую ответить.  Могу писать несколько сумбурно,  прошу извинить.

 

Если в две фразу то ответ такой:

1. Реляционная модель слишком строга для хранения химических данных в большинстве случаев.  Говоря проще в реляционной модели обычно больше порядка чем нам нужно

2. Использование JSON не запрещает сочетать его с реляционной моделью в тех случаях когда она оправдана.

 

Когда реляционная модель уместна?

Обычно это примерно такая история - есть список веществ и для каждого вещества есть некий набор свойств - температуры плавления и испарения,  растворяется ли в воде и полярных растворителях и растворяется ли в неполярных. Возможно ряд параметров известен не для всех веществ - ставим Null.  В принципе получается вполне приятная таблица - id,  название, формула - текстовая строка и ряд столбцов с параметрами.  Могут быть ссылки на внешние таблицы, например с перечнем источников и так далее

Внешне всё выглядит прекрасно.  Строим индексы и поиск работает шустро.  Master-slave или даже Master-master кластер тоже легко строится - данные редко изменяются,  чаще добавляются и постоянно читаются.  Соответственно проблемы с производительностью решаются обычным горизонтальным масштабированием

 

Эталонный пример хорошего случая для реляционного представления:

 

Соединение

Температура, °С Напряжение разложения, В
K2ZrF6 621 2,10
K2ZrF6 843 1,22
ZrCl4 621 2,20
ZrCl4 760 1,83
ZrCl4 843 1,41
ZrCl3 827 2,19
ZrCl2 827 2,34
HfCl4 827 2,00
HfCl3 827 2,36
HfCl2 827 2,46

 

 

Первое нарушение гармонии и радости можно заметить своими глазами - информация в таком виде не человекочитаема. Чтобы получить данные человек должен ввести некий sql запрос.  Это маленькая проблема, особенно пока таблиц мало. В крайнем случае создаём view (вьюха она же виртуальная таблица) и получаем что нужно в удобном виде.

 

Второе нарушение гармонии наступает когда начинаешь в это всё пытаться впихивать данные поступающие "с мест".  Поступают они в виде скажем так - как Бог, вернее коллега пришлёт.

 

Например

Экстрагент

Коэффициент распределения Степень извлечения, %
фтора SO42- P2O5 фтора SO42- P2O5
Этанолдиактиламин 20,7 7,8 0,5 77,3 56,0 8,1
Триоктиламин 19,1 5,1 0,4 75,8 45,5 5,6
Триалкиламин 16,3 3,3 0,2 72,7 34,9 2,9
Триакилбензиламмониймонофосфат 12,1 3,2 0,2 68,2 34,0 2,8
Триалкилметиламмонийсульфат 6,4 2,6 0,1 51,5 29,8 1,7
Фосфиноксид (разнорадикальный) 15,1 4,1 2,0 71,4 40,0

0,2

 

 

Вот эта  таблица уже в реляционную модель не лезет. Её нужно разделять как минимум на три таблицы - Коэффициент распределения + Степень извлечения + Экстрагент

 

И каждый раз прилетает заметка совсем в своём виде. значит приходится разбираться отдельно

 

 

И наконец третий акт пьесы - запись реакций.  Этот зверь в реляционную модель совершенно не влезает. 

С точки зрения структур данных запись уравнения реакции это как минимум упорядоченная пара двух неупорядоченных наборов строк.

Упорядоченная пара потому что у нас есть реагенты и продуктов реакции.  Да реакция может быть обратимой или даже периодической (не химик, поправьте если не прав) но в любом случае что то у нас "слева" и что то "справа"

Но при этом порядок записи самих реагентов и продуктов - значения не имеет.  Нет разницы C+02=C02  или O2+C=C02.

Ещё бывает нужным указать агрегатное состояние реагентов и продуктов - получается что нужна упорядоченная пара двух неупорядоченных наборов строк.  И ещё бывает нужны условия протекания - среда какая или физическое воздействие.  Получаем ещё набор неких величин

 

Запись химических реакций естественным образом в реляционную модель никак не вкладывается.  Любая такая попытка будет сопровождаться кучей искусственных ограничений.

 

Зато в json легко:

{
    "name": "Simple reaction",
    "required": [
        "C",
        "O"
    ],
    "product": [
        "C02"
    ],
    "termodinamic_resoult": "exotermic"
}

 

Заврался:

{
  "name": "Simple reaction",
  "compouds":[
    {"C":"C", "O2":"O2"},    
    {"C02":"CO2"},  
 ],
   "termodinamic_resoult": "exotermic"
}

 

 

 

Ну и последнее - использование json НЕ обозначает что нужно отказываться от реляционных баз данных и соответствующих благ цивилизации.  Ни в коем случае обратно к кострам и каменным топорам не зову:-)

 

В postgresql можно легко хранить и json и сочетать с обычными таблицами и строить кластеры и пр.  Есть и специализированные БД

 

Изменено пользователем silentlyinmay
Ссылка на комментарий

Вы фактически назначили веществам названия колонок: реагенты, продукты и получили опять реляционную таблицу.

 

Как-то думал, какая простейшая реляционная база возможна. Получилась база из 3 таблиц: параметр - свойство - связь.

Ссылка на комментарий
В 10.01.2024 в 07:36, chemister2010 сказал:

Вы фактически назначили веществам названия колонок: реагенты, продукты и получили опять реляционную таблицу.

 

Как-то думал, какая простейшая реляционная база возможна. Получилась база из 3 таблиц: параметр - свойство - связь.

 

Давайте посмотрим как примерно выглядит реляционная БД химических реакций.  Как уже писал уравнение химической реакции как минимум есть упорядоченная пара двух неупорядоченным множеств символов - списков реагентов и и продуктов.  Основное условие - мы должны уметь различать химические реакции,  каждая реакция должна быть уникальна.  По сути это ведёт к двум моделям:

 

CREATE TABLE REACTIONS (REACTION_ID INT PRIMARY KEY, 
                        REACTION_NAME VARCHAR, 
                        REACTION_REMARK VARCHAR);  // Создаём список всех реакций 

CREAT TABLE INPUT_COMPOUDS (COMPOUD VARCHAR,

                                                               STOICHIOMETRY_NUMBER INT, 

                                                               REACTION_ID REFERENCES REACTIONS (RECTION_ID),

                                                               PRIMARY KEY(COMPOUD, REACTION_ID));     // Создаём таблицу с реагентами,  таблица с продуктами реакции аналогично

 

или же можно реагенты и продукты реакции свести в одну таблицу просто поставив логический признак реагента/продукта - true или false

 

опять же таблицы можно расширить столбцами для описания условий реакции - pH среды, факторы инициации  и аналогично с веществами

 

Вы такую конструкцию имеете в виду?

 

 

 

 

Ссылка на комментарий
В 12.01.2024 в 07:04, chemister2010 сказал:

 

Да.

 

А теперь давайте посмотрим как это можно делать при помощи JSON и современной БД.  В данном случае это PostgreSQL.  К сожалению в разных БД работа с JSON организуется несколько по разному.  Даже между MySQL и её форком MariaDB есть различия,  хотя частичная совместимость сохраняется.  Тут много что можно обсудить поэтому к делу:

 

// Создаём таблицу

CREATE TABLE json_reactions (
  id serial primary key,
  data jsonb
);

 

// Запишем немного данных

NSERT INTO json_reactions (data) VALUES
('{
  "name": "Simple reaction",
  "compouds":[
    {"C":"C", "O2":"O2"},
    {"C02":"CO2"}
 ],
   "termodinamic_resoult": "exotermic"
}')

 

INSERT INTO json_reactions (data) VALUES
('{
  "name": "Simple reaction",
  "compouds":[
    {"H2":"H2", "O2":"O2"},
    {"H02":"HO2"}
 ],
   "termodinamic_resoult": "exotermic"
}')


INSERT INTO json_reactions (data) VALUES
('{
    "name": "Simple reaction",
    "required": [
        "C",
        "O"
    ],
    "product": [
        "C02"
    ],
    "termodinamic_resoult": "exotermic"
}


INSERT INTO json_reactions (data) VALUES
('{
    "name": "Горение гремучего газа",
    "required": [
        "H",
        "O"
    ],
    "product": [
        "H20"
    ],
    "termodinamic_resoult": "exotermic"
}');

INSERT INTO json_reactions (data) VALUES
('{
    "name": "Получение эфира из спират",
    "required": [
        "CCO"
    ],
    "product": [
        "CCOCC"
    ],
    "termodinamic_resoult": "endotermal",
    "enviroment": "OS(O)(=O)=O"
}');

 

 

//  А теперь попробуем найти запись о реакции у которой например есть условия среды

 

test=# SELECT * FROM json_reactions WHERE data ?|array['test1', 'enviroment'];
 id |                                                                        data                                                                         
----+-----------------------------------------------------------------------------------------------------------------------------------------------------
  4 | {"name": "Получение эфира из спират", "product": ["CCOCC"], "required": ["CCO"], "enviroment": "OS(O)(=O)=O", "termodinamic_resoult": "endotermal"}
(1 строка)

test=#

 

 

И самое главное - необходимости отказываться от традиционной реляционной модели нет

 

Ссылка на комментарий
В 08.01.2024 в 18:43, silentlyinmay сказал:

Доброго времени суток всем!

 

Решил поделится небольшим наблюдением и размышлениями. Возможно кому-то будет полезно или кто то  подскажет более изящный подход

...

 

учить структуры данных и прийти к пониманию что такое бд, реляционная модель, методы обмена данными между сервисами. Для начала, может каша и сварится.

Ссылка на комментарий
В 14.01.2024 в 20:38, deviantdev сказал:

учить структуры данных и прийти к пониманию что такое бд, реляционная модель, методы обмена данными между сервисами. Для начала, может каша и сварится.

 

Хотелось бы услышать начальника транспортного цеха т.е. хотелось бы конкретных идей или конструктивной критики

Ссылка на комментарий
В 14.01.2024 в 21:05, silentlyinmay сказал:

 

Хотелось бы услышать начальника транспортного цеха т.е. хотелось бы конкретных идей или конструктивной критики

Куда ещё конкретней?) повторю - Учить структуры данных и прийти к пониманию что такое бд, реляционная модель, методы обмена данными между сервисами. Можно добавить к списку методы хранения больших объемов данных, раз уж такой разговор пошел. 

Потом появится понимание что, когда и как использовать. Иначе совсем не выполняете обязанности data engineer'a)

Ссылка на комментарий

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...