Search code examples
mysqlmysql-workbenchentity-relationshipaggregation

How to implement an Aggregation in SQL? (This is not about GroupBy)


In the scope of a university project I am supposed to implement an aggregation of my database.
I'm given a Entity-Relationship model which looks similar to this one: Example for an Aggregation as a Entity-Relationship model Now I'm supposed to implement a SQL-Script which creates a database like this, but I cannot find anything about this topic on google or anywhere else. In the slides of my Professor it says

  • For example, to represent aggregation manages between relationship works_on and entity set manager, create a schema
    manages(employee_id, branch_name, title,manager_name)
  • Schema works_on is redundant provided we are willing to store null values for attribute manager_name in relation on schema manages

So I tried to just put two tables into my SQL-Script one called works-on and one called manages. In works-on I put all the Primary keys of job, branch and employee and defined them as foreign keys. In manages I put all of these Primary keys and additionally I put manager. Now the problem is that when I use the Reverse-Engineer of MySQL-workbench to create the EER-Model of the database, I don't get anything out of it which has to do with this aggregation. So what am I doing wrong here?
As requested by @Barmar I just wrote the CREATE TABLE-statements that I would've used for this:

CREATE TABLE job
(jobid INT,
PRIMARY KEY(jobid));

CREATE TABLE employee
(employeeid INT,
PRIMARY KEY(employeeid));

CREATE TABLE branch
(branchid INT,
PRIMARY KEY(branchid));

CREATE TABLE manager
(managerid INT,
PRIMARY KEY(managerid));

CREATE TABLE works_on
(jobid INT, KEY(jobid),
branchid INT, KEY(branchid),
employeeid INT, KEY(employeeid));

CREATE TABLE manages
(jobid INT, KEY(jobid),
branchid INT, KEY(branchid),
employeeid INT, KEY(employeeid),
managerid INT, KEY(managerid));

ALTER TABLE works_on
ADD CONSTRAINT FK_workson_employee FOREIGN KEY(employeeid) REFERENCES employee(employeeid);
ALTER TABLE works_on
ADD CONSTRAINT FK_workson_branch FOREIGN KEY(branchid) REFERENCES branch(branchid);
ALTER TABLE works_on
ADD CONSTRAINT FK_workson_job FOREIGN KEY(jobid) REFERENCES job(jobid);

ALTER TABLE manages
ADD CONSTRAINT FK_manages_employee FOREIGN KEY(employeeid) REFERENCES employee(employeeid);
ALTER TABLE manages
ADD CONSTRAINT FK_manages_branch FOREIGN KEY(branchid) REFERENCES branch(branchid);
ALTER TABLE manages
ADD CONSTRAINT FK_manages_job FOREIGN KEY(jobid) REFERENCES job(jobid);
ALTER TABLE manages
ADD CONSTRAINT FK_manages_manager FOREIGN KEY(managerid) REFERENCES job(managerid);

Solution

  • Your ER-Diagram is missing an important information: the cardinality between the manager and the new entity that is built from the other 4 elements job, employee, manager, branch and works-on (this new entity is marked by the square around them).

    From the quote on the slides we can deduce that it is a 0..1-relationship, that means every combination of job, branch and employee (or every entry in works-on) has at most one manager, but does not require one (in contrast to e.g. a composition).

    But you will have to verify that cardinality in your actual task.

    You can oftentimes implement an ER-diagram in several ways, but the slides imply the following realization:

    CREATE TABLE manages
    ( jobid INT not null,
      branchid INT not null,
      employeeid INT not null,
      managerid INT null,
      PRIMARY KEY (jobid, branchid, empoyeeid)
    );
    

    I omitted the trivial foreign keys to the tables job, employee, manager and branch.

    With this implementation, you do not have an explicit table for the works-on-relation anymore, just like the second statement in your slides says. It is included in the manages table. That's only possible for a 0..1-relation, which is why that cardinality was deducable.

    If you want to keep a table for works-on, you would use

    CREATE TABLE works_on
    ( jobid INT not null,
      branchid INT not null,
      employeeid INT not null,
      PRIMARY KEY (jobid, branchid, empoyeeid)
    );
    
    CREATE TABLE manages
    ( jobid INT not null,
      branchid INT not null,
      employeeid INT not null,
      managerid INT not null,
      PRIMARY KEY (jobid, branchid, empoyeeid),
      FOREIGN KEY (jobid, branchid, employeeid) 
        REFERENCES works_on (jobid, branchid, employeeid)
    );
    

    Again, I omitted the trivial foreign keys.

    To simplify the foreign key (and maybe to emphasize that the combination is considered a new entity), you can, as @Barmar proposed, add an additional (usually auto-increment) key to the works_on-table and use this value in the manages-table, although the slides do not do this here.

    In case you need to implement a 0..n-relation (several manager can manage a specific works-on-combination), you cannot absorb the works-on-relation in the manages-relation anymore (so you need both tables), and to respect the n, you will have to include managerid in the primary key, PRIMARY KEY (jobid, branchid, empoyeeid, managerid) (but still need to keep the FOREIGN KEY (jobid, branchid, employeeid)).