首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组合键的组合键

问组合键的组合键
EN

Stack Overflow用户
提问于 2012-05-18 19:17:59
回答 3查看 392关注 0票数 3

我正在尝试了解对我正在创建的数据模型采取什么方法。我有两个表,它们是我最初使用组合键创建的。我现在正在添加第三个表,这是前两个表的连接表,这将导致三个字段和两个外键的组合键,每个字段2个字段。这很可能是在MySQL中实现的,并与某种Java持久性框架一起使用。我一直喜欢使用组合键,因为它似乎是一种更自然的表示数据的方式,但我希望确保以后不会让自己陷入痛苦的境地。我应该继续使用前面提到的方法,还是只在表上创建一些自动递增的I?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-05-18 19:24:32

Hibernate推荐使用纯技术的、自动生成的、非组合键(纯连接表除外)。有很好的理由,国际海事组织。

使用组合键,您的映射会困难得多。由于更复杂的索引,性能会降低。一般的编程会比较困难,因为不能只用一个长字符来标识一个给定的实体,你需要两个或三个长字符(例如,考虑URL和表单,你必须在你的URL/表单中放上两个或三个参数/隐藏字段)。

当然,如果键是功能性的,情况就更糟了,因为有时您将不得不更改主键的一个部分,这将迫使您更新对此主键的所有引用。

票数 2
EN

Stack Overflow用户

发布于 2012-05-18 19:21:10

如果您的多对多是纯关系(本身没有属性),并且永远不会被引用,那么只需使用组合键即可。

如果它可能有自己的属性或被引用(比如实例化为一个类),你可能想要有一个代理键,因为许多ORM都要求id是一个整数。

票数 2
EN

Stack Overflow用户

发布于 2012-07-23 20:45:19

当涉及到约束与外键的更深层次的关系时,连接表的代理键有一个巨大的缺点。我们需要一个6表的设置来演示它。

基表:

代码语言:javascript
复制
CREATE TABLE semester (semester_id INTEGER PRIMARY KEY, semester_name VARCHAR(40));
CREATE TABLE student  (student_id  INTEGER PRIMARY KEY, student_name  VARCHAR(40));
CREATE TABLE subject  (subject_id  INTEGER PRIMARY KEY, subject_name  VARCHAR(40));

然后让我们将它们连接起来:

代码语言:javascript
复制
CREATE TABLE enrollment (
  enrollment_id INTEGER PRIMARY KEY,
  semester_id INTEGER NOT NULL,
  student_id INTEGER NOT NULL,
  room_number INTEGER,
  FOREIGN KEY (semester_id) REFERENCES semester (semester_id),
  FOREIGN KEY (student_id)  REFERENCES student  (student_id),
  UNIQUE INDEX (semester_id, student_id)
);

-- similarly ...
CREATE TABLE class(class_id ..., semester_id ..., subject_id ..., class_number ...);

到目前为止,一切都很棒。但是,我们需要将它们更多地联系起来:

代码语言:javascript
复制
CREATE TABLE grades (
  student_in_class_id INTEGER PRIMARY KEY,
  enrollment_id INTEGER NOT NULL,
  class_id INTEGER NOT NULL,
  grade char(1),
  FOREIGN KEY enrollment (enrollment_id),
  FOREIGN KEY class (class_id),
  UNIQUE INDEX (enrollment_id, class_id)
);

问题:,我们到底应该如何强制招生和上课都引用同一个学期呢?(简短的回答:we‘t)

组合键也是如此--在这里我不需要额外的键来强制外键的唯一组合,默认情况下主键会为我做这件事:

代码语言:javascript
复制
CREATE TABLE enrollment (
  semester_id INTEGER NOT NULL,
  student_id INTEGER NOT NULL,
  room_number INTEGER,
  PRIMARY KEY (semester_id, student_id),
  FOREIGN KEY (semester_id) REFERENCES semester (semester_id),
  FOREIGN KEY (student_id)  REFERENCES student  (student_id)
);

-- along the same lines...
class(semester_id ..., subject_id ..., class_number ...)

然后是不祥的等级表:

代码语言:javascript
复制
CREATE TABLE grades (
  semester_id INTEGER NOT NULL,
  student_id INTEGER NOT NULL,
  subject_id INTEGER NOT NULL,
  PRIMARY KEY (semester_id, student_id, subject_id),
  FOREIGN KEY (semester_id, student_id) REFERENCES enrollment(semester_id, student_id),
  FOREIGN KEY (semester_id, subject_id) REFERENCES class(semester_id, subject_id)
);

通过这种方式,我可以正确地表达和约束我的关系。

额外的好处:我可以通过简单的连接获得我的semester_name、student_name和subject_name值(而不必遍历多个级别的模式)。您可能会有比这个最简单的示例更多的级别,然后它将更加明显地返回到任何父关系是多么容易。

更改模式并不复杂,但即使是这样:数据建模不就是对数据进行建模吗?仅仅因为我们喜欢代理键,我们就可以抛弃引用完整性吗?

注意: Hibernate可以处理组合键。Ruby的DataMapper也是如此。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10651647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档