关系数据库设计中,用中间表好还是直接设定主外键关联好?

有人会对数据库有这样的疑问:

因为大多数的数据库教程上都是告诉你关系数据库如何去创建1:1、1:N和N:M的数据库关系,但我发现很多开源产品中,并没有直接使用关系数据库的关系查询、关系删除等功能,而是直接在代码中对多个表的查询结果进行组合。

这两种方式的优缺点是什么呢?为什么很多项目都选择后者呢?在一个中型以上的项目实践中,我该选择哪种方式,或是两种方式结合使用?

我想:

1,数据表与数据表之间有关联(Relationship)是肯定的,但是不一定要用外键(Foreign Key),为什么?外键本质是一种约束(Constraint),该约束决定了你在增删改查的时候都会有额外开销。【实际上数据库在处理外键的时候估计也是创建一个中间表根据中间表来做关联操作,完成后再删除】

2,“对于 “N对N” 的关系,两个 Model 之间肯定是需要一张中间表的,比如 Student、Class 之间选课关系,是多对多的,肯定需要一张 Enroll 的表来维持,记录两个表的主键(Primary Key),但是不需要在数据库层加外键约束,只需要加两个索引,或作为联合主键。

3,至于查询,尽量不用 JOIN。但是问题是我确确实实是需要知道多个表的信息。
比如我要知道某门课(Class,已知 ID)的信息,同时还有选上该课(Enrolled)的学生信息(Student)。
使用 JOIN ?没问题,我相信你可以写出一个很长的 JOIN 语句。
但是,可能有的地方大概这样实现的(伪代码):


  1. getClassInfo(@class_id)
  2. { SELECT class_col1, class_col2 FROM class WHERE class.id = @class_id }
  3. getStudentInfo(@class_id)
  4. { SELECT student_col1, student_col2 FROM student WHERE student.id IN (SELECT enroll.student_id FROM enroll WHERE enroll.class_id = @class_id) }

两种方案各有优缺。
后者最大的一个优点是灵活,比如我们引入缓存(Caching)。
一般来说,一个学校 class 数量不多,并且经常被查询,系统可能会引入缓存层(如 memcached、redis)来存放 class 对象。
那么上面的 getClassInfo 其实会变为

  


  1. {
  2.   if(memcached.has(@class_id) != null)
  3.   {
  4.       return memcached.get(@class_id);
  5.   }
  6.  
  7.   //查询数据库(只有 class 表),和上面的 SQL 一样
  8.   memcached.set(@class_id, class_object);
  9.   return class_object;
  10. }
时间: 2024-10-21 17:25:55

关系数据库设计中,用中间表好还是直接设定主外键关联好?的相关文章

解析SQL 表结构信息查询 含主外键、自增长_Mysql

最近项目需要做什么数据字典,需要表结构信息.在网上看了许多关于表结构信息的查询,感觉都不怎么样.相对好一点就是<基于SQL2005 SQL2008 表结构信息查询升级版的详解(含外键信息)> ,但是这里有一点小问题,缺少一个过滤以致运行有一点小bug.在AdventureWorks2012数据库中的Address表查询结果如图:在查询过滤中我们添加以下信息就ok了:AND g.class_desc = 'OBJECT_OR_COLUMN'修改后的SQL如下: 复制代码 代码如下: SELECT

oracle修改一个表中的主键字段值,与其外键关联的另一个表中的相应字段值也改变

问题描述 oracle修改一个表中的主键字段值,与其外键关联的另一个表中的相应字段值也改变 oracle 中修改一个表中的主键字段值,与其外键关联的另一个表中的相应字段值也改变? 有如下两张表,表a和表b 表a 结构如下: ID Name age 1 lisi 18 2 wangwu 21 3 sunliu 34 4 yiliu 24 ... ... ... 其中ID字段为表a主键且自增 表b结构如下: CID CNAME ID 1 aaaaa 1 2 bbbbb 2 3 cccccc 4 4

探讨SQL利用INFORMATION_SCHEMA系统视图如何获取表的主外键信息_Mysql

接着上篇文章<解析SQL 表结构信息查询 含主外键.自增长>里面提到了INFORMATION_SCHEMA视图,其实到了SQL 2005微软都主推大家使用INFORMATION_SCHEMA系统视图,而不是在使用sys东东了,当然目前还是有许多信息只能通过sys视图来查询.这里我们还是以查询表结果信息为例来说明一些主要的INFORMATION_SCHEMA视图的使用.首先我们需要查询列的信息,这需要用到[INFORMATION_SCHEMA].[COLUMNS]系统视图来查询数据列的信息,SQ

oracle中如何判断本表有多少张表对其有外键关联

在oracle中如何判断本表有多少张表对其有外键关联?我们主要分为两步: 第一步:        //查询表的主键约束名 select * from user_constraints e where e.table_name='' -----此处输入表名 第二步:        //查询所有引用到该主键的记录 select b.table_name,b.column_name from user_constraints a inner join user_cons_columns b on a.

在PowerDesigner中设计物理模型1——表和主外键

原文:在PowerDesigner中设计物理模型1--表和主外键 在PD中建立物理模型由以下几种办法: 直接新建物理模型. 设计好概念模型,然后由概念模型生成物理模型. 设计好逻辑模型,然后由逻辑模型生成物理模型. 使用逆向工程的方法,连接到现有的数据库,由数据库生成物理模型. 物理模型能够直观的反应出当前数据库的结构.在数据库中的表.视图.存储过程等数据库对象都可以在物理模型中进行设计.由于物理模型和数据库的一致性,接下来以数据库对象和物理模型对象的对应来一一介绍: 表 新建物理模型时需要指定

数据库该如何设计 主外键应该怎么建

问题描述 数据库该如何设计 主外键应该怎么建 现在想做一个类似糗事百科的网站 数据库不知道怎么弄 求大神帮忙! 解决方案 简单来说,主键就是在1对多关系中1的那个,外键就是多的那个.比如两个表:User表有id,Topic表有userid,那么前者是主键,后者是外键. 解决方案二: 其实要做得简单的话,直接几个表就OK了 一个糗事记录表 ID 内容 一个糗事详细记录表 ID 内容 分类(热门.精华.....) 其他一些需要加的内容 踩还是赞 一个评论表 ID 楼层 评论内容 图片路径 踩还是赞

在Hibernate框架中编写持久对象类实现外键关联的几点注意事项

关系数据库系统本身就比较复杂,加上Hibernate的O/R映射层,复杂度加重了,很容易出现问题,本人将最近遇到的问题和解决方法做一个总结,整理在下面的一系列文章中 正确理解Hibernate的聚合类型(collection)的使用 在Hibernate中正确实现关联关系中的级联操作(cascading) 在Hibernate框架中编写持久对象类实现外键关联的几点注意事项 本文是第三篇,讲解在one-to-many(一对多)关联关系中的对象类的几个关键方法的实现.主要是equals(),hash

架构师-创建表结构的时候,需要创建外键吗?

问题描述 创建表结构的时候,需要创建外键吗? 有的同事说,不创建外键,因为容易出错. 我觉得只要表结构正确,为什么会出错呢? 解决方案 建议不要使用关联. 主要是我们不建议你真正去从数据库中删除数据,而是通过一个字段标记实现伪删除. 这样的好处是,数据可以追溯. 回到你的问题,表之间有了关联,涉及到级联删除的问题.如果外键的数据被删除,另一侧的数据全部需要级联删除.这是不推荐的. 解决方案二: 不建议外键,尤其涉及修改和删除的时候.可以自己建几张表测试下,违反外键约束常有的事 解决方案三: 一般

powerdesigner-【新兵营】PowerDesigner中如何生成的Ldm只有主外键

问题描述 [新兵营]PowerDesigner中如何生成的Ldm只有主外键 大家好!我想请问下PowerDesigner中如何生成的Ldm只有主外键,例如这样的![图片说明](http://img.ask.csdn.net/upload/201602/17/1455699737_92325.jpg) 每张表都只显示外键跟主键,并且表明他们的关系, 谢谢大家!祝大家新年快乐! 解决方案 用的比较少:看看这个文章吧!http://blog.csdn.net/zhang6622056/article/