简体   繁体   English

需要算法或MySQL查询建议

[英]Algorithm or MySQL Query Advice Needed

I am in desperate need of either algorithm or query construction assistance. 我非常需要算法或查询构造帮助。

We have a user-generated, flexible database that is created using a form builder we have created. 我们有一个用户生成的灵活数据库,该数据库是使用我们创建的表单构建器创建的。 The data for these forms is stored in two tables as follows: 这些表单的数据存储在两个表中,如下所示: 在此处输入图片说明

The instances table tell us what form the user is viewing, and then the instance_records table has all the data for the instance. 实例表告诉我们用户正在查看哪种形式,然后instance_records表包含该实例的所有数据。 The field_id column tells us what field on the form the data maps to. field_id列告诉我们数据映射到表单上的哪个字段。 The reason we use a single table like this instead of creating a table for each form is that MySQL limits how many columns we can have in table given that the data is varchar of a significant length. 我们使用像这样的单个表而不是为每种形式创建表的原因是,鉴于数据是相当长的varchar,MySQL限制了表中可以包含多少列。 One possibility would be to use Text fields for the data, but then we would lose the built in MySQL searching capabilities. 一种可能是使用文本字段作为数据,但是那样我们将失去内置的MySQL搜索功能。

Things work quite well and very fast on basic forms. 在基本形式上,事情运行得很好而且非常快。 The problem is that one instance of a form can refer to another instance of the form. 问题在于表单的一个实例可以引用该表单的另一实例。 For example, we have user created form called Appointments. 例如,我们有用户创建的名为“约会”的表单。 On this form, it refers to the Patient form, the Technician form, the Doctor form, etc. 在此表单上,它是指“患者”表单,“技术员”表单,“医生”表单等。

So, on the Appointment form with instance id, the value for the patient field is actually an instance id of a patient, the doctor field value is the instance id for the doctor, etc. At the first level of references, things aren't too bad. 因此,在具有实例ID的“约会”表单上,“患者”字段的值实际上是患者的实例ID,“医生”字段的值是医生的实例ID,以此类推。在第一级引用中,情况并非如此太糟糕了。 But, you can have chains of references. 但是,您可以具有引用链。 I can have a prescription that refers to an appointment that refers to a patient, etc. So, if I want to get the value of the patient name on the prescription, I have to follow the chain down to get the right instance id and field id for the data. 我可以有一个处方,该处方指向一个病人的约会,依此类推。因此,如果我想获取该处方上病人姓名的值,则必须遵循以下步骤来获取正确的实例ID和字段数据的ID。

So, if I want to do a report on Appointments and show the Patient name, the Doctor name, and the Technician name, I have to go through some hoops. 因此,如果我想生成一份有关约会的报告,并显示患者姓名,医生姓名和技术人员姓名,我必须经历一些麻烦。 What I have tried is creating views and then joining the views to a final view that shows all the data for the query. 我尝试过的工作是创建视图,然后将这些视图连接到最终视图,以显示查询的所有数据。 But, it eats a ton of memory and starts writing the view temporary tables to disk and gets slow as all heck. 但是,它占用了大量内存,并开始将视图临时表写入磁盘,并且变得非常慢。 Using query caching, the second time the report runs, it's fast as heck. 使用查询缓存,报表第二次运行时,速度很快。 But, that first run can take over a minute once we get above 5000-7000 instances. 但是,一旦达到5000-7000个实例,第一次运行可能需要一分钟以上。

Something tickling at the back of my mind is that there might be some sort of a way to store the data in a way that I can take advantage of some faster tree search algorithms. 我脑海中tick动的是,可能存在某种方式来存储数据,从而可以利用一些更快的树形搜索算法。

You should read up on EAV... This article might give you some ideas ... It talks about two different approaches for storing values. 您应该阅读EAV ... 本文可能会给您一些想法 ...它讨论了两种存储值的方法。 Either approach you end up having a single query for any given form that would essentially grab all the values for the master entity (in this case the form). 无论哪种方法,您最终都会对任何给定的表单进行单个查询,该查询实际上将获取主实体(在这种情况下为表单)的所有值。 Then either on the application side or the db side you aggregate those values together appropriately for the application to consume. 然后在应用程序端或数据库端,将这些值适当地聚集在一起,以供应用程序使用。

The form itself should be a single atomic unit that has a list of fields, you dont need to store which form a field actually comes from you just need to store it as a field on the complete form. 表单本身应该是具有字段列表的单个原子单元,您不需要存储字段实际来自哪个表单,只需将其存储为完整表单上的字段即可。 You should develop logic for merging the fields to a single form on the application side during the creation process. 您应该开发逻辑,以便在创建过程中将字段合并到应用程序端的单个表单。

It sounds like you're trying to create a database in a database. 听起来您正在尝试在数据库中创建数据库。 There's a dailywtf link I'm looking for somewhere... 我正在某处寻找Dailywtf链接...

Anyway, it sounds like you need an Appointment table, and a Patient table, and a Doctor table, and a Technician table, and then you need to join them properly. 无论如何,听起来您需要一个“约会”表,一个“病人”表,一个“医生”表和一个“技术员”表,然后您需要正确地加入它们。

For example, to see the patients, doctors, and techs from the appointments yesterday, you might do 例如,要查看昨天约会中的患者,医生和技术人员,您可以

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

Edit: Let's give the example of Patient with a variable number of fields 编辑:让我们以可变字段数为例

Table Patient - contains data ALL patients will have 表患者-包含所有患者将拥有的数据

| 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 |
+------+-------------+-------------------+-------

Table Patient-Form 表格患者表格

| 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  |
+-----------+------------------+----------+---------------|

Table Patient-Form-Field - contains data that may or may not be available for a patient Table Patient-Form-Field(患者表格表格字段)-包含可能无法提供给患者的数据

| 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     |
+------------+-----------+------------------+------------+

You can now query this like this: 您现在可以像这样查询:

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")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM