开发者

Implementing super-type subtype correctly in MySQL

Below is a diagram of a database in which I am trying to determine the appropriate design for. Here are a few notes.

  • Employees/managers are associated with customers.
  • The partyid is a way to globally represent a person; customer, employee, manager. 开发者_开发百科Does it need to propagate all the way down? Should it be a primary key in all tables or just the tables that represent an individual?
  • Do the other tables such as billing, reporting, credential, etc tables need to have their own respective id's that are primary keys, e.g. billingid, reportingid, credentialid, etc?

Some notes about the interaction of the entities.

  • employees have a manager(s) associated with them.
  • customers have a manager(s) and possibly employees associated with them.
  • customers and employees will need to report time billed.

Implementing super-type subtype correctly in MySQL


The table "party" doesn't look right. Compare to the source code from this other SO question.

In this kind of structure, the party id number does propagate downward, so to speak. It should usually be either a primary key or a foreign key in tables that store data about a person.

In your table "reporting", it looks like the primary key shouldn't be 'partyid'. That would allow only one row per employee, which I don't think you intended. (I could be wrong.) If I'm right about that, you might consider a NOT NULL UNIQUE constraint on {partyid, date}, and a PRIMARY KEY constraint on a new column, 'reportid'. The tables "travel" and "performance" would probably reference 'reportid'. (But keep reading.)

There are places in your diagram where an entity gets an additional key: your company assigns a unique employee id number to its employees, for example. There's no theoretical reason you can't use 'employid' instead of 'partyid' from that point on to reference employees. But there is a practical reason you might not want to do that. It increases the number of joins.

For example, if the tables "credential", "tool", "certification", "academic", and "compliance" referenced employee.employid instead of employee.partyid, you couldn't just join "compliance" and "party" to get the person's name. You'd have to join "employee", too.

Do the other tables such as billing, reporting, credential, etc tables need to have their own respective id's that are primary keys, e.g. billingid, reportingid, credentialid, etc?

They need to have a primary key; the primary key doesn't necessarily have to be an id number. If there's an existing natural key, you have to identify it and declare it UNIQUE anyway.

The table "orders" should probably have only "orderid" as its primary key; use a foreign key reference to identify the customer. In some cases, it makes sense to rename columns. In the case of customers, it might make sense to call its key 'customerid' instead of 'parytid'. I'd create a domain, myself.

create domain PARTY_ID as integer not null;

Then, everywhere that needed a party id number, I'd use the domain instead.

create table customers (
    customerid PARTY_ID primary key references parties (partyid),
...

I'd prefer to see a table of managers, too. A reference to it would guarantee that manager.managerid would resolve to an actual manager, not just to any employee.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜