You seem to use the word "database" when you mean "table." One database for all data is best. Most modern databases (PostgreSQL, MySQL, Oracle, DB2, SQL Server, etc.) can handle a large amount of data in one database. It sounds like you might want to access all customer and/or all invoice information together, so keep them together in one database.
Data should be split into separate tables to normalize it as needed. Fully normalized data (each piece of information stored only once) is recommended by every database textbook I have read. Read about (or at least Google) "database normalization" to understand that concept well.
One normalized approach would be to have one customer table indexed by a customer id with all fields common to every customer. The customer table would also have a field identifying the customer type: customer1, 2, ... 10. A separate table would hold customer-1-type fields, indexed by customer id. Another table would have customer-2-type fields, etc. The application using the database would be designed to look for data in the customer-1 table if the customer-type is customer1, look for data in customer-2 table if customer-type is customer2, etc.
Presumably, the relationship between customer and invoice is one to many. A invoice table could have a foreign key linking to the customer table. If invoice data varied by customer-type, then that data could be placed in separate tables: invoice-customer-type-1, invoice-customer-2, etc. When gathering invoice data, find the customer id for the invoice from the invoice table, look up the customer-type from the customer table, then get data from the appropriate invoice-customer-# table.
Also, the tables in the database should be structured how the data will be used. For data entry and updating, a normalized structure is good. For printing bills or other reporting, you might want to create temporary de-normalized tables to speed the process. Creation of a temporary table can be faster because you avoid making multiple table joins every time a bill is printed.
Get a textbook and study database design, but in the meantime, I hope this helps.
The first thing that catches my eye is what appear to be separate tables for each exam. This could get rather difficult to maintain in the future: if the structure of exams changes you need to update n tables. Also, any aggregate queries that cover all exams for 1 patient will need to join n tables.
I'd suggest a structure like this:
patient_exams
-------------
patient_exam_id (PK)
visit_id (FK)
patient_id (FK)
study_id (Fk)
exam_seq_num
(other fields)
Use exam_seq_num
to track which exam number the record is for a patient. You can use a composite key containing patient_id
, visit_id
, study_id
, exam_seq_num
to ensure that you don't get exams for a patient with duplicate sequence numbers. You'll still need a bit of code to create the correct sequence number, maybe an on-insert trigger.
UPDATE:
Ok, so now it's clear that the exame tables are actually for different types of exams.
You could have something like
base_exam
---------
id (PK)
patient_id (FK)
exam_date
(other stuff)
Lumbar_exam_details
-------------------
lumbar_exam_id (PK)
base_exam_id (FK to base_exam.id)
(other specific fields)
blood_exam_details
------------------
blood_exam_id (pk)
base_exam_id (FK to base_exam.id)
(other specific fields)
All of your exam detail tables reference the base_exam
table, which stores common fields for all exams (such as the date of the exam, the patient who was examined, etc...).
If you really want to have a "display name" for exam types, I would do that in a view that overlays the specific exam table. For example, the query for lumbar_exam_view
might look like:
SELECT *, "Lumbar Exam" AS DISPLAY_NAME
FROM LUMBAR_EXAM_DETAILS
Use this view in any queries/reports on lumbar_exam_details
you will have access to display_name
anywhere that you want the user-friendly string.
If you need the display name to be stored as actual data, you can add an exam_type_id
field to base_exam
and then have it point to an exam_type
table:
exam_type
---------
id
display_name
Data:
exam_types
ID | display_name
------------------
1 | Lumbar Exam
2 | Blood test
Now your base exam records have an ID that points them to the correct user-friendly string. Note that this does not ensure that the exam detail record is of the correct type (i.e. it is possible, for example, to have a base_exam
record that is referenced by lumbar_exam_details
, but the base_exame
record erroneously references the display name "Blood Test"
) - it only works on the display name.
Best Answer
good lord, no.
read up on multi-tenancy http://msdn.microsoft.com/en-us/library/aa479086.aspx
read up on the Party Model http://www.tdan.com/view-articles/5014/
read up on Table Inheritance http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
Then go read the data modeling books by Fowler, Silverston, or Hay.