I'm new in DataBases at all and have some difficulties with setting relationships between 3 tables in MS Access 2013.
The idea is that I have a table with accounts info, a table with calls related to this accounts and also one table with all the possible call responses. I tried different combinations between them but nothing works.
1st table - Accounts : AccountID(PK) | AccountName | Language | Country | Email
2nd table - Calls : CallID(PK) | Account | Response | Comment | Date
3rd table - Responses: ResponseID(PK) | Response
When you have a table, it usually has a Primary Key field that is the main index of the table. In order for you to connect it with other tables, you usually do that by setting Foreign Key on the other table.
Let's say you have your Accounts table, and it has AccountID field as Primary Key. This field is unique (meaning no duplicate value for this field).
Now, you have the other table called Calls and you have a Foreign Key field called AccountID there, which points to the Accounts table.
Essentially you have Accounts with the following data:
AccountID| AccountName | Language | Country | Email
1 | FirstName | EN | US | some#email.com
2 | SecondName | EN | US | some#email.com
Now you have the other table Calls with Many calls
CallID(PK) | AccountID(FK) | ResponseID(FK) | Comment | Date
1 | 1 | 1 | a comment | 26/10
2 | 1 | 1 | a comment | 26/10
3 | 2 | 3 | a comment | 26/10
4 | 2 | 3 | a comment | 26/10
You can see the One to Many relationship: One accountID (in my example AccountID=1) to Many Calls (in my example 2 rows with AccountID=1 as foreign keys, rows 1 & 2) and AccountID=2 has also 2 rows of Calls (rows 3 and 4)
Same goes for the Responses table
Using this table structure:
Accounts : AccountID(PK) | AccountName | Language | Country | Email
Calls : CallID(PK) | AccountID(FK) | ResponseID(FK) | Comment | Date
Responses: ResponseID(PK) | Response
Accounts.AccountID is referenced by Calls.AccountID. 1:n – many calls for one account possible, but each call concerns just one account.
Responses.ResponseID is referenced by Calls.ResponseID. 1:n – many calls can get the same response from the prepared set, but each call gets exactly one of them.
To actually define the Relationships in Access, open the Relationships window...
... then follow the detailed instructions here:
How to define relationships between tables in an Access database
Related
I'm trying to design a database that allows for filtering according to if a specific resource fills certain categories. I've gotten to the point where I can input data that seems to be how it should be filled out but I'm not sure how I should pull it out again.
The main resource table looks like this:
Table1 - resources
| resourceID | AutoNum |
| title | short text |
| author | short text |
| publish date | date |
| type | short text |
Table2 - Department Categories
| ID | AutoNum |
| 1 | Yes/No |
| 2 | Yes/No |
| fID| Number |
Table3 - Categories
| ID | AutoNum |
| cat | Yes/No |
| dog | Yes/No |
| bird | Yes/No |
| fID | Number |
I have built a form where you can fill in items to the resource ID, and at the same time check off the Yes/No boxes in tables 2 & 3.
I'm trying to use the primary key ID from table 1 and copy it into the table 2 & 3 with referential integrity to cascade deletes, updates. Which I think is the right way to do this.
Currently, I've learnt that I can implement a search function for the columns in table 1, this seems to work fine. However I am stuck with applying the relevant columns in table 2 and 3 as filters.
apply search>
[X] - Cats
Should only return records from table 1 where in table 3 the relevant column has a tick in the Yes/No box.
I hope I have explained this properly, very new to Access and databases so if you need clarity, don't mind offering.
I have a Person table, each of who's records belongs to a parent record from the Company table.
One Person is designated as "Organizer" for their parent Company. Initially I handled this by having a recursive reference from the Company table identifying the Person record that was it's "Organizer" - but the software I'm using to build my application layer falls over - it can't handle recursive references.
I've changed tack, and have added a bit field to the Person table to identify whether the person is an "Organizer" or not, but neet to ensure that there is only one "Organizer" for each Company record. If I use an AFTER UPDATE trigger on the Person table, an update on Person triggers an update on Person - obviously I want to avoid recursive triggers.
How can I ensure that there is only ever one Person marked as the "Organizer" for it's parent Company?
+-----------+---------+---------+-----------+ +-----------+---------+---------+-----------+
| FirstName | Surname | Company | Organizer | | FirstName | Surname | Company | Organizer |
+-----------+---------+---------+-----------+ +-----------+---------+---------+-----------+
| John | Smith | 1 | True | | John | Smith | 1 | True |
| Mike | Jones | 1 | NULL | | Mike | Jones | 1 | NULL |
| Fred | Green | 1 | NULL | | Fred | Green | 1 | NULL |
| James | McMahon | 2 | NULL | | James | McMahon | 2 | NULL |
| Philip | Stills | 2 | NULL | Making Philip organizer ==> | Philip | Stills | 2 | True |
| Hector | Berlioz | 2 | True | 'triggers' this change ==> | Hector | Berlioz | 2 | NULL |
+-----------+---------+---------+-----------+ +-----------+---------+---------+-----------+
So seeing as no-one has given an answer here, I'll post what I eventually did:
Created a separate table called Organizer, with only two fields:
CREATE TABLE Organizer (
Company int NOT NULL UNIQUE,
Person int NOT NULL,
CONSTRAINT FK_Organizer_Company FOREIGN KEY (Company) REFERENCES Company(ID) ON DELETE CASCADE,
CONSTRAINT FK_Organizer_Person FOREIGN KEY (Person) REFERENCES Person(ID) ON DELETE CASCADE,
CONSTRAINT PK_Organizer_ID PRIMARY KEY (Company, Person)
);
By making the Company field unique, I can only ever have one organizer for any company.
ON DELETE CASCADE prevents me ending up with orphan organizer records for companies or people that don't exist.
Can't quite recall why I made the PRIMARY KEY both fields. Doesn't seem to hurt.
It was then just a matter of checking for an existing Organizer record and updating that if it existed, or inserting one if it didn't. I did this in the application layer, though I could just have easily have made a Stored Procedure that took Company.ID and Person.ID parameters, checked for Organizer records with the former, and updated the table accordingly. Could even throw in a check for whether the Person actually belongs to that company, and return a value accordingly to the application layer.
I have to add a new table according to some new requirements, the model currently consists of two tables: DETAIL and SUMMARY.
The relation is that every detail has associated one summary, so now I need to add a new table called SUMMARY_ESP, which has the a FK ( SUMMARY) and two more columns, something like this:
ID | SUMMARY_ID | ESP_ID | PRIORITY_ESP | PTY_ID | PRIORITY_PTY
1 | 123 | 34 | 1 | 122 | 1
2 | 123 | 35 | 2 | 111 | 2
3 | 123 | 30 | 3 | null | null
4 | 1111 | 34 | 4 | null | null
Other tables info:
DETAIL TABLE
ID_DET | AMOUNT | DATE | ID_SUMMARY | EXTERNAL_ID
1 | 1000 | 14/05/2018 | 1111 | 4
2 | 2000 | 18/07/2016 | 1111 | 4
3 | 1200 | 11/07/2017 | 123 | 1
4 | 1300 | 21/09/2018 | 123 | 2
SUMMARY TABLE
ID_SUMMARY | PRIORITY| PROFILE | CLASS | AREA
123 | 1 | 1 | 5 | 3
1111 | 2 | 1 | 5 | 3
33 | 3 | 2 | 5 | 9
4 | 4 | 8 | 5 | 10
So according to this, SUMMARY_ID , ESP_ID and PTY_ID are unique, the thing is at some point to know the what is the ESP_ID of certain detail, but since the relation is with SUMMARY table, I have no idea which one was when it was added, so I was asked to create a new column to the DETAIL table called EXTERNAL_ID, so I can know what is the code from the SUMMARY_ESP.
So if the row is the first one, it can be either 24 or 122 in the new column according to some previous logic, but I'm worried about the implications this might have in the future, because somehow I might be duplicating information, also I would need to make some weird logic in order to get the priority depending on whether it's ESP_ID or PTY_ID.
The new table along with SUMMARY are somehow parameters table, their values do not change that often and only the PRIORITY column would change, DETAIL instead is more transactional, and it has insert and update everyday according to some business logic.
I was thinking of adding the ID of the new table as a FK to the DETAIL table, but at the end would be the same, because it'll be hard to maintain and update would be harder, also it's like a circular dependency, so I'm kind of stuck with this , so any kind of help would be really helpful, below the complete model, with the current idea.
Also I can't add those new columns to the table SUMMARY, because there could be more than one associated to the same code in that table and since it's the PK I cant add two rows with the same code.
The relation is that every detail has associated one summary
You need to represent that relationship in your database layout : if you have a 1-N relationship between SUMMARY and DETAIL, you want to create another column in DETAIL that holds the primary key of the SUMMARY record that it is related to.
With this relation in place, you can start from a DETAIL row, relate a row from SUMMARY and identifiy all SUMMARY_ESP records that are linked to it.
Now if you need to uniquely relate a DETAIL record to a SUMMARY_ESP record, then you want to either add a foreign key to SUMMARY_ESP in DETAIL, or the other way around (add a foreign key to DETAIL in SUMMARY_ESP), depending on the way your data flows.
Let's assume we have application with pages, posts and events. With each part of this application we want to have comments. Now let's take a look into tables for our DB.
1. One comment table, object and object_id as foreign key
Page/Post/Event has many comments, foreign key object, object_id
comments table
+-------------+-------------+-------------+-------------+
| id | object | object_id | text |
=========================================================
| 1 | Page | 1 | Comment 1 |
+-------------+-------------+-------------+-------------+
| 2 | Post | 1 | Comment 2 |
+-------------+-------------+-------------+-------------+
| 3 | Event | 1 | Comment 3 |
+-------------+-------------+-------------+-------------+
2. Multiple comments tables
Page (Post, Event) has many page comments, foreign key page_id
page_comments table
+-------------+-------------+-------------+
| id | page_id | text |
===========================================
| 1 | 1 | Comment 1 |
+-------------+-------------+-------------+
post_comments table
+-------------+-------------+-------------+
| id | post_id | text |
===========================================
| 1 | 1 | Comment 2 |
+-------------+-------------+-------------+
event_comments table
+-------------+-------------+-------------+
| id | event_id | text |
===========================================
| 1 | 1 | Comment 3 |
+-------------+-------------+-------------+
I have used specific example, but this can apply to any other 1:N tables or even with M:N (tags), but for simple showcase, this should be good.
We should discuss
Performance concerns
Design pros and cons
Initial thoughts
case 1 means less tables in DB, easier to read, reusable application code
case 1 is better when doing query on all comments (would have to use union at case 2)
case 2 is better in regards of normalization (3NF)
case 2 is easier to backup (dump) parts of the system, e.g. pages itself with their comments
case 2 should be better with performance because less rows => faster
for example i have table users, which have 3 fields:
id - login - password
---------------------
1 | john | *****
2 | jack | *****
3 | jane | *****
now i want that each user could have his own settings.
So, do i need to create three different tables, like
user_N_settings:
id | key | value
-------------------------
1 | save_data | True
or i should create one big table for all users instead?
users_settings:
id | key | value | user_id
---------------------------------------------
1 | save_data | True | 2
2 | some_opt | False | 3
One table for all users. A table per user would be very wrong.
One table. If all the setting values are of the same type then it may make sense to create one row per setting. If the attributes are all very different then create one column per setting.