我正在尝试了解对我正在创建的数据模型采取什么方法。我有两个表,它们是我最初使用组合键创建的。我现在正在添加第三个表,这是前两个表的连接表,这将导致三个字段和两个外键的组合键,每个字段2个字段。这很可能是在MySQL中实现的,并与某种Java持久性框架一起使用。我一直喜欢使用组合键,因为它似乎是一种更自然的表示数据的方式,但我希望确保以后不会让自己陷入痛苦的境地。我应该继续使用前面提到的方法,还是只在表上创建一些自动递增的I?
发布于 2012-05-18 19:24:32
Hibernate推荐使用纯技术的、自动生成的、非组合键(纯连接表除外)。有很好的理由,国际海事组织。
使用组合键,您的映射会困难得多。由于更复杂的索引,性能会降低。一般的编程会比较困难,因为不能只用一个长字符来标识一个给定的实体,你需要两个或三个长字符(例如,考虑URL和表单,你必须在你的URL/表单中放上两个或三个参数/隐藏字段)。
当然,如果键是功能性的,情况就更糟了,因为有时您将不得不更改主键的一个部分,这将迫使您更新对此主键的所有引用。
发布于 2012-05-18 19:21:10
如果您的多对多是纯关系(本身没有属性),并且永远不会被引用,那么只需使用组合键即可。
如果它可能有自己的属性或被引用(比如实例化为一个类),你可能想要有一个代理键,因为许多ORM都要求id是一个整数。
发布于 2012-07-23 20:45:19
当涉及到约束与外键的更深层次的关系时,连接表的代理键有一个巨大的缺点。我们需要一个6表的设置来演示它。
基表:
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));然后让我们将它们连接起来:
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 ...);到目前为止,一切都很棒。但是,我们需要将它们更多地联系起来:
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)
组合键也是如此--在这里我不需要额外的键来强制外键的唯一组合,默认情况下主键会为我做这件事:
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 ...)然后是不祥的等级表:
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也是如此。
https://stackoverflow.com/questions/10651647
复制相似问题