Multiple Foreign keys to a single table and single key pointing to more than one table

妖精的绣舞 提交于 2019-12-06 00:20:29

1 ...

There is nothing inherently wrong with this. If the possible user "roles" are strictly determined and unlikely to change, then this is, in fact, the preferred way to do it. You are effectively modeling the C:M relationship, where C is constant.

On the other hand, if the roles can change (e.g. you need to be able to dynamically add a new "lifecycle phase" to the defect), then a link (aka. junction) table, modelling the true M:N relationship, might be justified. Something like this:

BTW, while JOINs have their cost, that by itself doesn't mean you can't afford it. And you may not even need all the JOINs all the time - just do the JOINs that bring the information that you currently need and leave the others out. In any case, I recommend you measure on realistic amounts of data to determine if there is an actual performance problem.

2 ...

If there are many common fields, you can use inheritance1 to minimize the repetition of common fields and foreign keys. For example:

In this model, each "attribute" table (such as state and importance) is connected only once with the base, and through it to each of the "inherited" tables such as defect and task. No matter how many "inherited" tables you add, you'll still have just one connection per "attribute" table

This model essentially prevents the proliferation of "attribute" FKs, for the price of somewhat more cumbersome management of defects and tasks (since they are now split to "common" and "specific" portion). Whether this is a better balance than the old design is for you to decide...


1 Aka. category, subclass, generalization hierarchy etc...

For the first issue it seems to me like you might be better off decomposing the defects table to have a "line" table, that stores the history of the transactions on it, like being created, updated, assigned etc.

This has the benefit of being more flexible. A defect can more easily track the history of being updated and assigned to multiple people, being reopened etc., with multiple updates through time being clearly denoted.

You'd still have your defect table storing some general global state for the defect (perhaps things like status, priority etc., especially if you don't need to track the changes in these states), and you'll have a series of *defect_lines*, each with a foreign key pointing to the defect, and another foreign key pointing to the user, and a type field indicating whether it was "create", "update" etc.

Eg.

defect ( id, priority, status )
defect_line ( defect_id, timestamp, type, user, comment )

Depending on the assumptions you're fine with making, defect_id, timestamp, and user could be the primary key for a defect_line.


For the second issue, at least with the information you've given it seems that they share all the same properties - so are basically the same thing with a different type flag ("task" or "defect"), so why not just have them in the same table?

I'd probably call this task under the assumption that all defects can be viewed as tasks ("things to be fixed"), but all tasks are not defects - but this is all just semantics now.

If there are distinct, non-shared properties though, you might then get to the case that you could have the shared properties of a task/defect in a table, and tables for the properties specific to each, though they might be able to still share the same "line" detail structure. This then partly becomes a decision between normalisation and ease of use - it might be easier to have two tables that largely have the same properties instead of braking this down into multiple tables.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!