需要算法或MySQL查询建议

时间:2011-02-17 00:05:12

标签: php mysql algorithm performance memory

我迫切需要算法或查询构造帮助。

我们有一个用户生成的,灵活的数据库,使用我们创建的表单构建器创建。这些表单的数据存储在两个表中,如下所示: enter image description here

实例表告诉我们用户正在查看的表单,然后instance_records表包含该实例的所有数据。 field_id列告诉我们数据映射到表单上的字段。我们使用像这样的单个表而不是为每个表单创建表的原因是MySQL限制了我们可以在表中有多少列,因为数据是一个显着长度的varchar。一种可能性是使用Text字段作为数据,但之后我们将失去内置的MySQL搜索功能。

在基本形式上,事情运作良好且非常快。问题是表单的一个实例可以引用表单的另一个实例。例如,我们有用户创建的名为Appointments的表单。在此表格中,它指的是患者表格,技术员表格,医生表格等。

因此,在具有实例ID的约会表单上,患者字段的值实际上是患者的实例ID,医生字段值是医生的实例ID,等等。在第一级引用时,事物还不错。但是,你可以有引用链。我可以有处方,指的是指患者等的约会。所以,如果我想在处方上获得患者姓名的价值,我必须按照链向下来获得正确的实例ID和字段数据的ID。

所以,如果我想报告约会并显示患者姓名,医生姓名和技术员姓名,我必须经历一些箍。我尝试过创建视图,然后将视图加入到显示查询所有数据的最终视图中。但是,它占用了大量的内存并开始将视图临时表写入磁盘并且变得缓慢。使用查询缓存,第二次报告运行时,它就快了。但是,一旦我们达到5000-7000个实例,第一次运行可能需要一分钟。

在我的脑海里发痒的是,可能存在某种方式来存储数据,以便我可以利用一些更快的树搜索算法。

2 个答案:

答案 0 :(得分:2)

你应该阅读EAV ...... This article might give you some ideas ...它讨论了两种不同的存储方法。无论哪种方法,您最终都会对任何给定的表单进行单一查询,从而获取主实体的所有值(在本例中为表单)。然后,在应用程序端或数据库端,您可以将这些值合适地聚合在一起,以供应用程序使用。

表单本身应该是一个包含字段列表的单个原子单元,您不需要存储字段实际来自哪个表单只需要将其存储为完整表单上的字段。您应该在创建过程中开发用于将字段合并到应用程序端的单个表单的逻辑。

答案 1 :(得分:1)

听起来您正在尝试在数据库中创建数据库。有一个我正在寻找的dailywtf链接...

无论如何,听起来你需要一个约会表,一个Patient表,一个Doctor表和一个Technician表,然后你需要正确加入它们。

例如,要查看昨天约会中的患者,医生和技术人员,您可以

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