经历过几个大型项目了。项目中都尽最大可能地避免使用外键,理由:
1. 使用hibernate的情况下,配置外键关联麻烦,不能用代码生成工具。不使用外键时可以将dao接口、实现、dto的代码全部生成出来2. 认为大量使用外键会很大程度上降低数据库性能3. 使用外键的情况下,很多时候要造一批测试数据都会很麻烦,清除数据的时候也麻烦
不使用外键对系统的影响。数据完整性需要在应用程序中处理,这点我认为很不合理。数据库设计要做的工作是设计出合理的数据模型来,而不仅是分析出业务中的要素,然后建几张表做持久化。
将数据与数据完整性分离开来……   这样的数据库设计我是很难认同的。分离后,应用程序中的检查需要的性能开销不也是存在的吗,还会将数据完整性检查嵌入到业务逻辑中来(不可避免,但我觉得是不是这种影响越小越好),,关于性能方面的考虑。使用外键会带来性能问题吗,影响有多大?
 在子表insert 的时候数据库维护数据完整性会有开销,这个开销是什么情况我很想看看测试数据。但是在关联查询时比不用外键的效率会高,查询优化器会利用到外键的设计。(没有考虑子表update delete,我也是凭感性的认识认为这2个操作没有完整性维护的开销,实际情况还没有了解)
在insert delete维护父表的时候,会对所有子表全表锁定!所以需要对外键都建索引。大家需要清楚外键使用时的这个注意点,否则我也相信会有不可忽略的性能问题!
造测试数据和清理数据时遇到的不方便之处是我认为最不能成为理由的理由。
因为测试的方便而放弃数据库的数据完整性??     对于大型和较大型项目中通常存在的避免使用外键这种情况我确实还很不理解。上面我提出问题时所得到的一些回答。
    向大家请教更充分的理由。性能方面希望能得到有说服力的分析统计信息

解决方案 »

  1.   

    http://blog.csdn.net/miraclestar/article/details/5819185正方观点: 
    1 ,由数据库自身保证数据一致性,完整性,更可靠,因为程序很难 100 %保证数据的完整性,而用外键即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。 
    eg :数据库和应用是一对多的关系,A应用会维护他那部分数据的完整性,系统一变大时,增加了B应用,A和B两个应用也许是不同的开发团队来做的。他们如何协调保证数据的完整性,而且一年以后如果又增加了 C 应用呢? 
    2 ,有主外键的数据库设计可以增加 ER 图的可读性,这点在数据库设计时非常重要。 
    3 ,外键在一定程度上说明的业务逻辑,会使设计周到具体全面。 反方观点: 
    1 ,可以用触发器或应用程序保证数据的完整性 
    2 ,过分强调或者说使用主键/外键会平添开发难度,导致表过多等问题 
    3 ,不用外键时数据管理简单,操作方便,性能高(导入导出等操作,在 insert,   update,   delete   数据的时候更快) 
    eg: 在海量的数据库中想都不要去想外键,试想,一个程序每天要 insert 数百万条记录,当存在外键约束的时候,每次要去扫描此记录是否合格,一般还不止一个字段有外键,这样扫描的数量是成级数的增长!我的一个程序入库在 3 个小时做完,如果加上外键,需要 28 个小时!    结论: 
    1 ,在大型系统中(性能要求不高,安全要求高),使用外键;在大型系统中(性能要求高,安全自己控制),不用外键;小系统随便,最好用外键。 
    2 ,用外键要适当,不能过分追求 
    3 ,不用外键而用程序控制数据一致性和完整性时,应该写一层来保证,然后个个应用通过这个层来访问数据库。 
      

  2.   

    反正我们项目也不用foreign key,组长说效率低,而且数据迁移会报错。。还有hibernate那个inverse特别难用。。
      

  3.   

    第1个理由:你用过hibernate?
    第2个理由:性能?搞笑吗?如果真的关注性能的话,为什么要用Hibernate,扇自己脸?ibatis,jdbc性能不比hibernate强?
    用hibernate无非用得就是面向对象的思想,在数据库里以对象的概念来保存,没有外键,何来1对多,多对1,多对多的关系?
    第3个理由: 你用过hibernate? 
      

  4.   

    还有数据库迁移的问题,为什么会报错?因为你们数据库工具用多了,或者说只会用工具!工具是傻的,他只知道按顺序来进行导入导出!
    你们有试过用命令来导库?
    导出
    mysqldump -u 用户名 -p 数据库名 > 导出的文件名导入mysql -u 用户名 -p 密码 数据库名字 < 导入的sql文件 setcharacter= 编码方式
    还有sorce命令 别自己傻,怪人家东西不好?凡事多问个为什么