I am using MS Access 2016 and I created tables (entities) Employees and Managers with the following attributes:
Employees
-EmployeeId (Primary key)
-Name
-LastName
-Email
-Phone
Managers
-ManagerId (Primary Key)
-EmployeeId (Foreign Key & Unique)
-Position
I am trying to create a relationship between the 2 entities that meet the following requirements:
Managers(EmployeeId) is a unique value.
for every record in Managers table there has to be one record in the Employees table (because the manager is an employee)
I can create a one to one relationship between the tables and I think that is fine because there can only be one ManagerId per EmployeeId (When the employee is actually a manager) but my issue is that when I add a record in my Employees tables Access is forcing me to have a record in the managers table even when I am adding a non-manager to the Employees table. Any suggestions on how I can create a relationship between the 2 tables is greatly appreciated.
When defining a relationship using the visual Relationships window, Access usually does a good job determining which is the primary table and which is the "related" table based on the indexes of the fields being related. But for a 1-to-1 relationship where the indexes on both fields are unique, Access uses the first table you click as the primary table and the second table--the one you dragged the first field onto--as the related table. Thus, it requires that a value be in the primary table before the related table record can be added. I assume that you defined the relationship by click and dragging in the wrong order/direction.
Delete the existing relationship between the tables. Then redefine the relationship by first clicking on the Employees.EmployeeId field, then dragging that field to the Managers.EmployeeId. The relationship window which pops up should show Table/Query: Employees on the left with Related Table/Query: Managers on the right.
This is in relation to an Access Database. I have a first table that lists employees with a primary key of id. In the first table, I include all employees (whether overlords or underlings). I have a second table that identifies approvals of expenses. I have one column that is a foreign key referencing the underling that made the expense. I have a second column in the same table that is a foreign key referencing the overlord that approved the expense. When creating a query, the query breaks because of the dual relationship. Could someone help me with some code to put in the query to lookup the overlord from the employees table based on the overlord id? Thanks.
I think I have it solved using the DLookUp Function. It looks something like this:
Overlord: DLookUp("[employee_name]", "employees", "ID = " & overlord_id)
I would still like to know if there is a way of doing this just with relationships.
I have the next design doubt:
I have athlete entity, the athlete can have many nationalities, so I have second table called countries. Then between athlete and countries there is a many-to-many relationship. I create another table athlete_country to resolve the many-to-many relationship.
My question: Is there a way to achieve that athlete_country entry be mandatory for any entry in the athlete table?
I am working on postgresql. Is there a way in another database server?
No, this is not possible to do it this way for logical reason: athlete_country tables references athlete table, and if you do back reference (in fact you can do it) you will not be able to insert any row in either table because each row should reference to the row in another table, which isn't inserted yet.
The solution is to use many-to-one relationship in addition to many-to-many which you have described. For example, you can add "primary_country" field to athlete table which references directly to the country table. In that case you can be sure that any athlete has relationship with at least one country, specified in "primary_country" field and, optionally, with other countries listed in the athlete_country table.
create table country(id serial primary key, name text);
create table athlete(id serial primary key, name text, primary_country int references country(id));
create table athlete_country(athlete_id int references athlete(id), country_id int references country(id), primary key (athlete_id, country_id));
I have a SQL Server database and it contains a table to record a employee salary.
It has 3 columns declared as foreign keys, and reference to the employee table's column, employee_id:
employee_id
submitted_by
confirmed_by
But is it best practice to make it all as FK, or do I only need employee_id?
Because in my application, submitted_by and confirmed_by will be selected by a drop down list and assume it exist on employee table.
Thanks you for advice.
Yes, since all users of your system are also Employees modelled by your system, if you wish to have Referential Integrity (RI) enforced in the database, all three columns should have foreign keys back to the referenced employee table. Note that since confirmed by sounds like part of a workflow process, where the user confirming may not be available at the time the record is inserted, you can make the field confirmed_by in table EmployeeSalary nullable (confirmed_by INT NULL), in which case RI will only be enforced at the later time when the field is actually populated.
You should name each of the foreign keys appropriately by expressing the role in the foreign key, e.g.
FK_EmployeeSalary_SalariedEmployee
FK_EmployeeSalary_EmployeeSubmittedBy
FK_EmployeeSalary_EmployeeConfirmedBy
Although the front end may restrict choices via the drop down, referential integrity is still beneficial:
Protect against bugs, e.g. where the submitted by employee is omitted (in the case of a non-nullable FK) or the employee provided doesn't exist in the employees table.
Prevent accidental deletion of an employee to which foreign key data is linked.
There is a (very) minor performance penalty on RI whereby the DB will need to check the existence of the PK in the employee table - in most instances this will be negligible.
Any column that references a key in another table should be declared as a foreign key. This way, if you mistakenly try to put a nonexistent value there, the database will report an error.
I have a problem that can be summarized as follow:
Assume that I am implementing an employee database. For each person depends on his position, different fields should be filled. So for example if the employee is a software engineer, I have the following columns:
Name
Family
Language
Technology
CanDevelopWeb
And if the employee is a business manager I have the following columns:
Name
Family
FieldOfExpertise
MaximumContractValue
BonusRate
And if the employee is a salesperson then some other columns and so on.
How can I implement this in database schema?
One way that I thought is to have some related tables:
CoreTable:
Name
Family
Type
And if type is one then the employee is a software developer and hence the remaining information should be in table SoftwareDeveloper:
Language
Technology
CanDevelopWeb
For business Managers I have another table with columns:
FieldOfExpertise
MaximumContractValue
BonusRate
The problem with this structure is that I am not sure how to make relationship between tables, as one table has relationship with several tables on one column.
How to enforce relational integrity?
There are a few schools of thought here.
(1) store nullable columns in a single table and only populate the relevant ones (check constraints can enforce integrity here). Some people don't like this because they are afraid of NULLs.
(2) your multi-table design where each type gets its own table. Tougher to enforce with DRI but probably trivial with application or trigger logic.
The only problem with either of those, is as soon as you add a new property (like CanReadUpsideDown), you have to make schema changes to accommodate for that - in (1) you need to add a new column and a new constraint, in (2) you need to add a new table if that represents a new "type" of employee.
(3) EAV, where you have a single table that stores property name and value pairs. You have less control over data integrity here, but you can certainly constraint the property names to certain strings. I wrote about this here:
What is so bad about EAV, anyway?
You are describing one ("class per table") of the 3 possible strategies for implementing the category (aka. inheritance, generalization, subclass) hierarchy.
The correct "propagation" of PK from the parent to child tables is naturally enforced by straightforward foreign keys between them, but ensuring both presence and the exclusivity of the child rows is another matter. It can be done (as noted in the link above), but the added complexity is probably not worth it and I'd generally recommend handling it at the application level.
I would add a field called EmployeeId in the EmployeeTable
I'd get rid of Type
For BusinessManager table and SoftwareDeveloper for example, I'll add EmployeeId
From here, you can then proceed to create Foreign Keys from BusinessManager, SoftwareDeveloper table to Employee
To further expand on your one way with the core table is to create a surrogate key based off an identity column. This will create a unique employee id for each employee (this will help you distinguish between employees with the same name as well).
The foreign keys preserve your referential integrity. You wouldn't necessarily need EmployeeTypeId as someone else mentioned as you could filter on existence in the SoftwareDeveloper or BusinessManagers tables. The column would instead act as a cached data point for easier querying.
You have to fill in the types in the below sample code and rename the foreign keys.
create table EmployeeType(
EmployeeTypeId
, EmployeeTypeName
, constraint PK_EmployeeType primary key (EmployeeTypeId)
)
create table Employees(
EmployeeId int identity(1,1)
, Name
, Family
, EmployeeTypeId
, constraint PK_Employees primary key (EmployeeId)
, constraint FK_blahblah foreign key (EmployeeTypeId) references EmployeeType(EmployeeTypeId)
)
create table SoftwareDeveloper(
EmployeeId
, Language
, Technology
, CanDevelopWeb
, constraint FK_blahblah foreign key (EmployeeId) references Employees(EmployeeId)
)
create table BusinessManagers(
EmployeeId
, FieldOfExpertise
, MaximumContractValue
, BonusRate
, constraint FK_blahblah foreign key (EmployeeId) references Employees(EmployeeId)
)
No existing SQL engine has solutions that make life easy on you in this situation.
Your problem is discussed at fairly large in "Practical Issues in Database Management", in the chapter on "entity subtyping". Commendable reading, not only for this particular chapter.
The proper solution, from a logical design perspective, would be similar to yours, but for the "type" column in the core table. You don't need that, since you can derive the 'type' from which non-core table the employee appears in.
What you need to look at is the business rules, aka data constraints, that will ensure the overall integrity (aka consistency) of the data (of course whether any of these actually apply is something your business users, not me, should tell you) :
Each named employee must have exactly one job, and thus some job detail somewhere. iow : (1) no named employees without any job detail whatsoever and (2) no named employees with >1 job detail.
(3) All job details must be for a named employee.
Of these, (3) is the only one you can implement declaratively if you are using an SQL engine. It's just a regular FK from the non-core tables to the core table.
(1) and (2) could be defined declaratively in standard SQL, using either CREATE ASSERTION or a CHECK CONSTRAINT involving references to other tables than the one the CHECK CONSTRAINT is defined on, but neither of those constructs are supported by any SQL engine I know.
One more thing about why [including] the 'type' column is a rather poor choice to make : it changes how constraint (3) must be formulated. For example, you can no longer say "all business managers must be named employees", but instead you'd have to say "all business managers are named employees whose type is <type here>". Iow, the "regular FK" to your core table has now become a reference to a VIEW on your core table, something you might want to declare as, say,
CREATE TABLE BUSMANS ... REFERENCES (SELECT ... FROM CORE WHERE TYPE='BM');
or
CREATE VIEW BM AS (SELECT ... FROM CORE WHERE TYPE='BM');
CREATE TABLE BUSMANS ... REFERENCES BM;
Once again something SQL doesn't allow you to do.
You can use all fields in the same table, but you'll need an extra table named Employee_Type (for example) and here you have to put Developer, Business Manager, ... of course with an unique ID. So your relation will be employee_type_id in Employee table.
Using PHP or ASP you can control what field you want to show depending the employee_type_id (or text) in a drop-down menu.
You are on the right track. You can set up PK/FK relationships from the general person table to each of the specialized tables. You should add a personID to all the tables to use for the relationship as you do not want to set up a relationship on name because it cannot be a PK as it is not unique. Also names change, they are a very poor choice for an FK relationship as a name change could cause many records to need to change. It is important to use separate tables rather than one because some of those things are in a one to many relationship. A Developer for instnce may have many differnt technologies and that sort of thing should NEVER be stored in a comma delimted list.
You could also set up trigger to enforce that records can only be added to a specialty table if the main record has a particular personType. However, be wary of doing this as you wil have peopl who change roles over time. Do you want to lose the history of wha the person knew when he was a developer when he gets promoted to a manager. Then if he decides to step back down to development (A frequent occurance) you would have to recreate his old record.