Необходим алгоритм или запрос MySQL - PullRequest
1 голос
/ 17 февраля 2011

Мне крайне необходим алгоритм или помощь в построении запросов.

У нас есть сгенерированная пользователем гибкая база данных, созданная с помощью созданного нами конструктора форм. Данные для этих форм хранятся в двух таблицах следующим образом: enter image description here

Таблица экземпляров сообщает нам, какую форму просматривает пользователь, а затем таблица instance_records содержит все данные для экземпляра. Столбец field_id сообщает нам, к какому полю формы относятся данные. Причина, по которой мы используем одну таблицу, подобную этой, вместо создания таблицы для каждой формы, заключается в том, что MySQL ограничивает количество столбцов, которые мы можем иметь в таблице, учитывая, что данные представляют собой varchar значительной длины. Одна возможность - использовать текстовые поля для данных, но тогда мы потеряем встроенные возможности поиска MySQL.

Вещи работают довольно хорошо и очень быстро на основных формах. Проблема в том, что один экземпляр формы может ссылаться на другой экземпляр формы. Например, у нас есть созданная пользователем форма под названием «Встречи». В этой форме это относится к форме пациента, форме техника, форме доктора и т. Д.

Таким образом, в форме «Назначение» с идентификатором экземпляра значение для поля пациента фактически является идентификатором экземпляра пациента, значение поля «доктор» является идентификатором экземпляра для доктора и т. Д. На первом уровне ссылок вещи не так уж плохо Но вы можете иметь цепочки ссылок. У меня может быть рецепт, который относится к назначению, которое относится к пациенту и т. Д. Поэтому, если я хочу получить значение имени пациента в рецепте, я должен следовать по цепочке вниз, чтобы получить правильный идентификатор и поле экземпляра. идентификатор для данных.

Итак, если я хочу сделать отчет о встречах и показать имя пациента, имя доктора и имя техника, мне нужно пройти через несколько обручей. Я попробовал создать представления, а затем соединить их с окончательным представлением, в котором отображаются все данные для запроса. Но он съедает тонну памяти и начинает записывать временные таблицы представления на диск и становится все медленнее. Используя кэширование запросов, во второй раз, когда отчет запускается, это быстро, как черт. Но этот первый запуск может занять более минуты, когда мы превысим 5000-7000 экземпляров.

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

Ответы [ 2 ]

2 голосов
/ 17 февраля 2011

Вы должны прочитать о EAV ... Эта статья может дать вам некоторые идеи ... В ней рассказывается о двух разных подходах для хранения значений. При любом подходе вы в конечном итоге получите один запрос для любой заданной формы, который по существу захватит все значения для главной сущности (в данном случае формы). Затем либо на стороне приложения, либо на стороне базы данных вы агрегируете эти значения вместе соответствующим образом для использования приложением.

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

1 голос
/ 17 февраля 2011

Похоже, вы пытаетесь создать базу данных в базе данных. Есть ссылка на dailywtf, которую я где-то ищу ...

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

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

SELECT 
  Appointment.start-time 
  Appointment.end-time 
  Patient.name 
  Patient.insurance-carrier 
  Doctor.name 
  Tech.name 
  Tech.home-lab
FROM Appointment
JOIN Patient on Appointment.patient-id = Patient.patient-id
JOIN Doctor on Appointment.doctor-id = Doctor.doctor-id
JOIN Tech on Appointment.tech-id = Tech.tech-id
WHERE Appointment.appointment-date = $YESTERDAY

Редактировать: Давайте приведем пример пациента с переменным количеством полей

Таблица пациента - содержит данные ВСЕ пациенты будут иметь

| ID   |    Name     | Insurance Carrier | .. other fields
+------+-------------+-------------------+-------
+ 0001 | John Doe    | ABC Healthcare    |
+ 0002 | Jane Doe    | ABC Healthcare    |
+ 0003 | Jon Skeet   | C# Insurance Inc. |
+ 0004 | Mark Byers  | Gold Badge Health |
+------+-------------+-------------------+-------

Таблица пациента-форма

| Form-Name |    Form-Field    | Required | Default-Value |
+-----------+------------------+----------+---------------|
| Vitals    | Blood Pressure   | TRUE     | null          |
| Vitals    | Pulse            | TRUE     | null          |
| Vitals    | Ear Temperature  | FALSE    | null          |
| Lab Work  | Lab Room         | TRUE     | Lab-001       |
| Lab Work  | Technician       | TRUE     | null          |
| Lab Work  | Insurance Covers | TRUE     | NO            |
| Payment   | Balance          | TRUE     | $0.00         |
| Payment   | Co-Pay           | FALSE    | 0.00%         |
| Payment   | Deductable       | FALSE    | $0.00         |
| Payment   | Payment Terms    | FALSE    | 30 Days Full  |
+-----------+------------------+----------+---------------|

Таблица Пациент-Форма-Поле - содержит данные, которые могут или не могут быть доступны для пациента

| Patient-ID | Form-Name |    Form-Field    | Form Value |
+------------+-----------+------------------+------------+
+ 0001       | Vitals    | Blood Pressure   | 130 / 54   |
+ 0001       | Vitals    | Pulse            | 84bpm      |
+ 0001       | Vitals    | Ear Temperature  | 98.4F      |
+ 0002       | Vitals    | Blood Pressure   | 126 / 74   |
+ 0002       | Vitals    | Pulse            | 87bpm      |
+ 0002       | Vitals    | Ear Temperature  | 99.0F      |
+ 0003       | Lab Work  | Lab Room         | SO-Meta    |
+ 0003       | Lab Work  | Technician       | Rose Smith |
+ 0003       | Lab Work  | Insurance Covers | TRUE       |
+ 0003       | Vitals    | Blood Pressure   | 190 / 100  |
+ 0003       | Vitals    | Pulse            | 213bpm     |
+------------+-----------+------------------+------------+

Теперь вы можете запросить это следующим образом:

SELECT 
  Patient.name 
  Patient-form-field.form-name 
  Patient-form-field.form-field 
  Patient-form-field.form-value
FROM Patient
JOIN Patient-Form-Field on ( Patient.patient-id = patient.id 
                         AND Patient-form-field in ("Vitals","Lab Work")
                           )
WHERE Patient.patient-id IN ("0001","0002","0003")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...