看了 CareySon 写的 数据库范式那些事儿 http://www.cnblogs.com/CareyS... 这篇文章之后,我感觉这篇文章内容还是有很多没有交代清楚的地方。
例如再讲1nf的时候表结构为
一般正常思维都是:员工ID唯一,那么肯定选择唯一的这个字段为主键,根本没人会用这种错误方式设计。
图上设计为:(员工ID,部门名称)为主键,那我也可以选择(员工ID,job_id)为主键,那么这个时候jobDescription又和主键中的部分字段job出现了部分依赖关系,同样违反范式。
而我自己平时设计数据库,都是直接根据需求,分析画出E-R图,找出映射关系为一对多or多对一or多对多,然后根据如下原则设计:
凡是一对多or多对一,在多的一方增加一个外键存储其映射的“一”的一方的主键,凡是多对多,则另外建一张表,然后这张表有两个字段(也可以是三个,每个关系本身有一个自增主键),这两个字段分别为两个“多”对应的主键。
按照我这个原则,根本不用理会1nf,2nf,3nf,4nf,甚至是5nf。在极端情况下(例如三个属性,两两之间互相组成候选码)理论上都能设计出符合第五范式的表。
至于BCNF,一般是选择一个自增主键或者guid(因为按照上述文章中提到的email或者username之类的字段做主键,实际关系数据库环境下可能会有性能问题)。(我不理解为什么违反BCNF就会导致增删改的异常?)
至于DKNF,我认为他是可以通过业务层代码(JAVA,PHP等)或者SQL的内置函数来完成根据域值计算域键的任务。或者也可以理解为是一种一对多关系(理解为某个域键和域值为一对多关系),然后按照上述原则来设计。
我这个原则是否能保证设计出一定符合所有数据库范式的关系数据表?
一般只有在教学的时候才会想着怎么去符合范式
而实际中 就如你所说 基本上按照习惯思路都是符合要求范式要求的 反而是想着是否需要为了性能考虑而去违反范式