I am fairly green when it comes to working with Access and databases in general.
I am asking for your help in figuring out how to set the correct relationships for three tables:
Table 1 contains:
(no unique ID)
SalesTripID
EmployeeName
StartDate
EndDate
*Each record on this table is related to 1 specific employee's 1 specific sales trip
Table 2 contains:
HotelName
HotelStart
HotelEnd
HotelTotal
*This table may contain multiple records that belong to only 1 record on table 1 (for instance, an employee would stay at 2 hotels during their sales trip)
Table 3 contains:
(no unique ID)
MealVendor
MealDate
MealTotal
*This table, similar to Table 2, may have multiple records in it that are tied to the 1 SalesTripID
How do I set something up to show me each SalesTripID, the multiple Table 2, and the multiple Table 3 records associated with it? Do I need to add a Primary Key anything other than Table 1? Is writing a query involved to display the information? Because I am so green, any and all feedback is welcome.
The following is my recommendation:
Add a SalesTripId field on tables 2,3. This is called a ForeignKey.
If SalesTripId in Table1 is not unique (i.e. each employee can have a trip with the same Id as another employee), add another field (Id) in Table1. You can use Access' AutoNumber type for that field.
I recommend always having a primary key in your tables. But you can skip the Id fields in tables 2,3.
Related
A very simple example. I have web API with a table in the database
Employees
---------
Id
---------
Name
and for example, I have 50 records.
Now I have to Implement a feature to add extra info about the department. Because I have one to many relationships the new database schema is with department id
Employees Department
---------- -----------
Id Id
--------- -----------
Name Name
---------
DepartmentId
for this, I run the query (i use SQL server)
alter table Employees add constraint fk_employees_departmentid
foreign key (DepartmentId) references Department(Id);
But now I have some issues to handle
1)Now I have the 50 existing records without departmentId. However, I must add manually this value? What is the best practice? For 50 records it is possible but for 2000 records and more?
2) when I add departmentId column I set this column to have null values(is correct?), but as a foreign key, I don't want to allow null values. Can I change it or how can I handle it?
1)Now I have the 50 existing records without departmentId. However, I must add manually this value? What is the best practice? For 50 records it is possible but for 2000 records and more?
It depends. You could set up a new department for "unassigned" and assign them all to that; you could send out a spreadsheet to HR saying "the following employees don't have an assigned department; what department are they in? ps; don't remove the EmployeeID column from the sheet before you send it back; i need it to update the DB". It's very much a business contextual question, not a technical one. X thousand records is easy to handle.. It'll just take a bit of time to work through if you (or someone else) is doing it manually. This information is likely to be available somewhere else; you could perhaps send a list out to all department heads saying "are any of these guys yours? Please remove all the names you don't have in your team from this spreadsheet and send it back to me" then update the DB based on what you get back
As this is a one time operation you don't need anything particularly whizz for it - you can just get your Excel sheet back and in an empty column put:
="UPDATE emp SET departmentID = 5 WHERE id = " & A1
And fill it down to generate a bunch of update statements, copy the text into your query tool and hit go; don't need to get all fancy loading the sheet into a table, doing update joins etc - just hacky style sling together something in excel that will write the SQL for you, copy/paste/run. If HR have sent back the sheet with a list of department names, then put the dept name and id somewhere else on the sheet and use VLOOKUP or XLOOKUP to turn the name into the department number, then compose your SQL based on that
2) when I add departmentId column I set this column to have null values(is correct?), but as a foreign key, I don't want to allow null values. Can I change it or how can I handle it?
Foreign keyed columns are allowed to have NULL values - it isn't the FK that imposes a "No Nulls" restriction, it's the nullability of the column (alter the column to departmantid INT NOT NULL) that imposes that. A FK references a primary key and the primary key may not be null (or in some DB, at most one record can have a [partly] null PK), but you could just leave those departments null. If you do alter the column to be not null, you'll need to correct the NULL values first or the change will fail
I need some guidance on designing the schema for invoices in a multi-tenant application.
I have a table called EmployeePay which holds all the information required to generate an invoice. The invoice table would have the invoice number, invoice created date and VAT rate. I am thinking to create a Sequence object for each Tenant to generate an invoice number.
EmployeePay Table: EmployeeID, Hours, Rate, InvoiceID (FK)
Invoice Table: InvoiceID (PK) (Identity), InvoiceNumber, InvoiceDate, VATRate, TenantID
Is it okay to have hundreds of Sequence objects in a database, as I’ll have to create one for each tenant? I’ll also have to create same amount of stored procedures which returns the next invoice number (I prefer a separate stored procedure for each tenant rather than having one large stored procedure with hundreds of choices in a select case statement).
Another concern is, is it theoretical to insert into the master table (Invoice) based on the transaction table (EmployeePay) and then use its primary key(InvoiceID) to update the transaction table?
Thanks in advance.
First make sure the relationship either this is one to many or many to many. If you are considering one employee that will have many invoices then its one to many relationship and you can create your table as under:
EmployeePay Table: EmployeeID (PK) (Identity), Hours, Rate
Invoice Table: InvoiceID (PK) (Identity), EmployeeID (FK), InvoiceNumber, InvoiceDate, VATRate, TenantID
EDIT:
I don't know which database you are using but for increment sequence check:
for MySQL check this LINK.
If you are using Oracle then check this LINK
I would suggest you to create another table can be called as InvoiceNumber, this will contain InvoiceNumberId(Int),TenantId (Fk), CurrentSequenceNumber(Int).
Significance of CurrentSequenceNumber is that it will be simple integer number which can be used to generate next Invoicenumber.InvoiceNumberId will be a Identity columns for Primary key purpose (you may or may not have it).
Structure of the Table will look like below.
Now you need to create only One Stored Procedure which will take input parameter as TenantId and will have responsiblity to generate next Invoice number by reading CurrentSequenceNumber from above table.
For example if we need to generate new Invoice Id for Tenant with id as 15 then SP will have your Business logic I am assuming Just creating a String with "Inv-" as prefix with incremented value of CurrentSequenceNumber so output of Procedure will be.
Inv-0009
Then after generation of this number SP will increment value to 9 for InvoiceNumberId 3.
So everything will be managed by Single table and Single procedure only.
I'm creating a clinic management system where I need to store Medical History for a patient. The user can select multiple history conditions for a single patient, however, each clinic has its own fixed set of Medical History fields.
For example:
Clinic 1:
DiseaseOne
DiseaseTwo
DiseaseThree
Clinic 2:
DiseaseFour
DiseaseFive
DiseaseSize
For my Patient visit in a specific Clinic , the user should be able to check 1 or more Diseases for the patient's medical history based on the clinic type.
I thought of two ways of storing the Medical History data:
First Option:
Add the fields to the corresponding clinic Patient Visit Record:
PatientClinic1VisitRecord:
PatientClinic1VisitRecordId
VisitDate
MedHist_DiseaseOne
MedHist_DiseaseTwo
MedHist_DisearThree
And fill up each MedHist field with the value "True/False" based on the user input.
Second Option:
Have a single MedicalHistory Table that holds all Clinics Medical History detail as well as another table to hold the Patient's medical history in its corresponding visit.
MedicalHistory
ClinicId
MedicalHistoryFieldId
MedicalHistoryFieldName
MedicalHistoryPatientClinicVisit
VisitId
MedicalHistoryFieldId
MedicalHistoryFieldValue
I'm not sure if these approaches are good practices, is a third approach that could be better to use ?
If you only interested on the diseases the person had, then storing the false / non-existing diseases is quite pointless. Not really knowing all the details doesn't help getting the best solution, but I would probably create something like this:
Person:
PersonID
Name
Address
Clinic:
ClinicID
Name
Address
Disease:
DiseaseID
Name
MedicalHistory:
HistoryID (identity, primary key)
PersonID
ClinicID
VisitDate (either date or datetime2 field depending what you need)
DiseaseID
Details, Notes etc
I created this table because my assumption was that people have most likely only 1 disease on 1 visit, so in case there's sometimes several, more rows can be added, instead of creating separate table for the visit, which makes queries most complex.
If you need to track also situation where a disease was checked but result was negative, then new status field is needed for the history table.
If you need to limit which diseases can be entered by which clinic, you'll need separate table for that too.
Create a set of relational tables to get a robust and flexible system, enabling the clinics to add an arbitrary number of diseases, patients, and visits. Also, constructing queries for various group-by criteria will become easier for you.
Build a set of 4 tables plus a Many-to-Many (M2M) "linking" table as given below. The first 3 tables will be less-frequently updated tables. On each visit of a patient to a clinic, add 1 row to the [Visits] table, containing the full detail of the visit EXCEPT disease information. Add 1 row to the M2M [MedicalHistory] table for EACH disease for which the patient will be consulting on that visit.
On a side note - consider using Table-Valued Parameters for passing a number of rows (1 row per disease being consulted) from your front-end program to the SQL Server stored procedure.
Table [Clinics]
ClinicId Primary Key
ClinicName
-more columns -
Table [Diseases]
DiseaseId Primary Key
ClinicId Foreign Key into the [Clinics] table
DiseaseName
- more columns -
Table [Patients]
PatientId Primary Key
ClinicId Foreign Key into the [Clinics] table
PatientName
-more columns -
Table [Visits]
VisitId Primary Key
VisitDate
DoctorId Foreign Key into another table called [Doctor]
BillingAmount
- more columns -
And finally the M2M table: [MedicalHistory]. (Important - All the FK fields should be combined together to form the PK of this table.)
ClinicId Foreign Key into the [Clinics] table
DiseaseId Foreign Key into the [Diseases] table
PatientId Foreign Key into the [Patients] table
VisitId Foreign Key into the [Visits] table
In my database I have some tables that looks something like:
table1
---------------
id name
table2
---------
id name ParnetId <-This is an ID from Table 1
table3
---------------
id name ParnetId <-This is an ID from Table 2
In the past, It seemed that the three tables are completely separate entities but now (due to a new requested feature...) I need to reference from another table any of the three tables.
Something like:
table4
---------------
id name foreignKey <-This ID should be from Table 1 OR Table 2 OR Table 3
So, I figured I could add a table that will hold the Id's for tables 1-3 and reference it from the table 4 (+ from tables 1-3 for the Id column).
Please note that I am working on a live database that already contains data.
My questions are:
Is there anything I need to watch out while performing the refactoring process?
How would I migrate the existing records id's from tables 1-3 to table 4 (relating to identical id's in the three tables)?
Is there a better strategy you can think of?
A new table (eg. CommonTable) with its own primary key, with nullable fields as foreign keys to table1, table2 and table3 seems like the way to go.
That way table4 can have a single foreign key to CommonTable, which may link to either table1 or table2 or table3.
A second approach would be to create a view (eg. CommonView) over table1, table2 and table3. You would need to concoct a fake primary key for this - perhaps "t1-xxx", "t2-xxx", "t3-xxx" for table1/2/3. I've used this technique as a temporary data migration mechanism, but wouldn't consider it as a long term solution.
A third approach, probably the easiest to implement, is simply to have multiple nullable foreign keys on table4:
table1Id
table2Id
table3Id
I would strongly advise against having a single field which is a foreign key to more than one table. I've seen this in action and it's a nightmare to work with. Think of the future developers confusion.
I would suggest having 7 tables in total table4, table1, table2, table3, t4t1link, t4t2link and t4t3link.
t4tXlink table should contain the primary keys from table4 and tableX. Thus you can have proper constraints in your database.
If you have just 1 table to contain 3 separate foreignkeys you can not have constraint that disallows values from other 2 columns.
Old version
I have a Person table and the table Company.
both tables have a column Id (Identity)
Table Company have Ids of 1 to 165
In the table Person have Ids 1 until 2029
New Version
In the new version of the system, was created a table Entity.
This table contains the records of the Companies and People
The Company and Person tables will be maintained, referring to the Entity table.
The Id in table Entity will be the same in Company or Person table
Question
Both tables have multiple relationships with other tables.
Table Entity (as well as others) has a column ID (identity).
The problem is that the Id were repeated when the two tables together (It was to be expected).
How to import without losing relationships?
Attempts
I thought of changing the value of Ids in Company table, starts from 2030.
Thus the Ids would not duplicate when joining the two tables.
But this creates another questions.
How to do this without losing existing relationships?
How to change the Id of a row in the table and this is reflected in all tables which it relates?
I would like to do this using only DDL (SQL Server)
I thought of changing the value of Ids in Company table, starts from 2030. Thus the Ids would not duplicate when joining the two tables.
Create foreign key constraints on the Person table to all related tables (or alter the existing foreign key constraints) with ON UPDATE CASCADE. Then update the Person table and change the values if the id columns - these changes will cascade to the related tables.
To stop further problems, maybe change the identity columns in Person and Company to something like identity( 1000, 3 ) and identity (1001, 3) respectively.
However, I think the best idea is to have a different EntityID column in the Entity table, unrelated to PersonID and CompanyID. The Entity table would also have a column called AltEntityID or BusinessKey that contains the id from the other table and that does not have a unique constraint or a foreign key constraint.
And if you make small modification to your attempt - add new column, say newId, to Company and to Person to manage relation with Entity and leave id columns as is. Why this is the simpliest way? Because new columns shouldnot be identity columns, from one side. From the other side, you can leave all logic of relating other tables with Company and Person intact.