I was unable to find a clear answer of how to create an IS_A relationship in Access.
There was the same question here, but without a concise answer:
IS_A relationship primary key validation rules
I have the entity Employee, and two sub-entities Loan_Officer and Branch_Manager. It's a school example of an IS_A relationship really.
I've managed to create A relationship, but there needs to be a constraint that an employee must be either a Loan Officer or a Branch Manager, but can not be both. Now, I can't figure out how to do this, because what ever I do, I can assign the same Employee_ID in both sub-entity tables at once.
I've connected the tables via the PK, as it's shown here:
Now, this table design is just something I've done, in order to be able to connect them via a one-to-one relationship. I had to set the PK of Loan_Officer to "Number" and not "AutoNumber", in order to be able to connect them. The other option is to have a separate PK in Loan_Officer, like "Loan_Officer_ID", and a foreign key, "Employee_ID" in the Loan_Officer table, but the results are again the same (also according to the ER Diagram, the sub-entities don't have a separate PK).
You can't. This is not a feature of the Access database.
You can create CHECK constraints to check for such conditions, but those don't offer features to cascade operations.
See this answer for an example on how to create a CHECK constraint.
There is no such thing as an 'Is A' relationship in databases between tables. This is instead a field in the Employee table or Employee History Table.
The issue of 'can't be both' is a matter of validation logic. Where this validation logic is applied is probably at the form object level (during data entry), not the table level (no data should ever be entered directly into tables by end users).
Look into Access Data Macros . They can be used like SQL triggers firing off when a record is INSERTed, UPDATEed, DELETEed etc.
Related
Here I have a EER diagram I am creating in the MySQL editor.
I want Person to relate to employee. I want some Persons entries to be employees/Customers/etc.
How would I implement this? Would it be a shared key? Join the tables? Related data?
I tried making EmployeeID a foreign key to PersonID. The tables still don't "relate". (There's no way to tell what employee X's name/dob/ect is.)
I encourage you to try again in the direction of making employeeID refer to personID, as a foreign key. You may not have implemented the whole idea.
The technique has a name: Shared Primary Key. If you search on this phrase, you will find articles describing what you have to do when adding a new employee. Without taking the correct steps when a new employee is added, you break the relationship between the two tables.
There is a tag with this name here in StackOverflow. shared-primary-key
What you are basically doing is setting up a situation where employee is a subclass of person. In an object-oriented system, this would be easy. SQL is not object oriented at the base level.
To start off, we have the following scenario (not exactly like this but for confidential reason I will not take the risk to explicitly describe the project) where let's say A person can Have Many home addresses and obviously an address belong to at most one person. This is pretty much a one to many relationship where there are 2 tables (Person and Addresses) with the second one holding a FK referencing the owner. But sadly i was told that my system should also allow users to enter Addresses first, so a FK that does not exist in the Person table yet. I came to the conclusion that i just have to drop that constraint. Do you thing it's a common thing to do? Furthermore I thought to maintain consistency even without FK (declared explicitly), if someone update the Person ID, since i dont want the user to do it in both table, is it possible to create a Trigger (I'm using Mysql server) that will update the second table automatically (if that person has an address)? If yes, any hint to how to write that (I'm not familiar with triggers)
You can maintain the 1:N relationship by creating the kind of intermediate table normally associated with M:N relationships but adding a uniqueness constraint on the address referencing field; alternatively, you can just make address' reference to person nullable, making it an optional reference.
[Edit]
Scripts from MySQL dump wrap their contents with something like:
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS=0;
....
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
As you can probably guess, it temporarily turns off foreign key checks to allow inserting interdependent data out of order. However, you should be sure of the trustworthiness of the import data as I believe it does not recheck the data when turned back on (so it can allow data that violates FK constraints to persist).
If you need the ability to add "address" before "person" with user entered data, then you are back the original situation of needing optional keys or another table; or just not actually saving the "address" info (but instead holding it locally in the data entry program) until after the "person" info is sufficient/complete.
If I have a TABLE that consists of a LIST of attributes of one TYPE and another TABLE that is also composed by the same TYPE of LIST, so how can I implements them into MySQL without having to create two TABLES of the same TYPE?
For example:
Like the EMPLOYEE table, the COMPANY table has a list of ADDRESSES.
And I want to implement without having to make one table ADDRESS for COMPANY and another for EMPLOYEE, as in this case:
To me the solution seems to be a dual relationship where one of the foreign keys must be null while the other may not be, but I don't even know how to do it.
I believe your underlying hyopthesis is flawed: a one-person Company, founded by an Employee, could be registered at the founder's personal adress. Therefore an Employee may have the same address as a Company.
Likewise, two Employees may share the same address (a husband and a wife could be coworkers). Therefore I would define the relationship between adress and each of the other two entities a regular many-to-many, without any further condition.
You might be worried that changing the address of (eg.) a Company would wrongly alter the Employee's address. But instead of updating the Address entity, treat this case as creating a new Address and linking the (eg.) Company to this new Address.
Now, if you really need to implement the constraint, regardless of the (oh so dull ;) reality, I see no other option but implementing a form of inheritance as decribed here.
Notice that:
your initial design actually implements the Single Table Inheritance pattern
your alternative proposal (based on two separate address tables) actually implements the Concrete Table Inheritance pattern1
In your initial design, the constraint can be implemented with a simple CHECK constraint2 on the address table, the condition being company_id IS NULL XOR employee_id IS NULL
1 Migrating to the Class Table Inheritance pattern is "left as an exercise". However this pattern does not help in enforcing this constraint (in fact, this elegant pattern has serious additional limitations with enforcing integrity constraints in general). Nevertheless the constraint could still be enforced with a CHECK constraint.
2 MySQL does not enforce CHECK constraints, but a similar effect can be achieved through the use of triggers.
I'm using MySQL / InnoDB, and using foreign keys to preserve relationships across tables. In the following scenaro (depicted below), a 'manager' is associated with a 'recordLabel', and an 'artist' is also associated with a 'recordLabel'. When an 'album' is created, it is associated with an 'artist' and a 'manager', but both the artist and the manager need to be associated with the same recordLabel. How can I guarantee that relationship with the current table setup, or do I need to redesign the tables?
You cannot achieve this result using pure DRI - Declarative Referential Integrity, or the linking of foreign keys to ensure the schema's referential integrity.
There are 2 ways to solve this problem:
Consider the requirement a database problem, and use a trigger on INSERT and UPDATE to validate the requirements, and fail otherwise.
Consider the nested link a business logic requirement, and implement it in your business logic in PHP/C#/whatever.
As a sidenote, I think the structure is rather strange from a practical perspective - as far as I know an Artist is signed to a RecordLabel, and assigned a Manager separately (either from the label or individually, many artists retain their own manager when switching to another label). Linking the Manager also to the Album only makes sense to record historic managers, enabling you to retrieve who was the manager to the artist when the album was released, but that automatically means your requirement is invalid if the artist switches labels and/or manages later on. I think therefore it is wrong from a practical data view to enforce this link.
What you do is add recordLabel id to the albums table. Then you put two, two column indexes on albumns (recordLabel_id, artist_id) and (recordLabel_id, managers_id).
Because the record_id can only have one value in each row of the albumns table you will have insured integrity.
I am modelling a relational database where the following schema is used to describe 2 tables: ERD Model.
The rules specified are that:
An office has a manager
Each staff member is assigned to an office
In order to model this I created an ERD using MySQL workbench, which provided the following DDL.
The issue I have is that in order to enforce that an office must have a manager, the foreign key in the office table is not nullable. Likewise, the foreign key in the staff table representing the office they work for is required for every staff and therefore not nullable. This makes sense to me in the model, however for the implementation it makes it impossible to insert data as each rely on the existance of tuples in the tables.
The only answer I can think of is to make the keys nullable such that one can temporarily exist without the other.
Is this the correct way to resolve the issue? The database will eventually be normalised to 3NF perhaps BCNF.
The problem is that you're attempting to record the relationship between offices and staff twice. Once in the office record and again in the staff record. You should only record the relationship in one place. Often this is done in a cross-reference table with two columns: Office_ID and Staff_ID. But it's also common to skip the third table and just record the relationship in one of the tables.
In this case, you can eliminate your problem by removing the Office field and foreign key from the Staff table. You'll be able to create as many Staff records as you need. Then when you create an Office record, you will be able to assign one of the Staff to the Office.