0

虽然我已经写了很长时间的 php,但它始终是我自己学会的一项技能,而且我刚刚遇到了关于表连接的小信心危机!

假设一个 MySQL 数据库auth包含 MyISAM 表userspermissions

users
- id (auto increment)
- email

permissions
- id (auto increment)
- name

为了以多对多(或一对多)的形式加入这些表,我一直使用这样的桥接表:

user_permissions
- id (auto increment)
- user_id
- permission_id

(我知道 innoDB 能够建立关系,但它也更复杂并且占用更多内存,所以出于 q 我想留在 myISAM 的目的)

我的特殊问题是:使用自动递增键加入表是否明智,还是应该生成自己的附加键?

我知道如果表损坏并且我必须重建或者如果我开始镜像到两个数据库并且密钥不同步,则可能会出现问题。

我也知道,如果我为每一行生成一个唯一的哈希(用于连接),那么在每次数据插入之前生成一个哈希并检查它是否是新的都会产生开销。

其他人是如何做到的?这些问题是您在实际情况中看到的吗?

谢谢你的时间!

亚当

4

2 回答 2

0

权限和用户的加入将如下所示:

SELECT      u.*, p.*
FROM        user_permissions up
INNER JOIN  users            u
ON          up.user_id = u.id
INNER JOIN  permissions      p
ON          up.permission_id = p.id

user_permission 中的id列并不是必需的,除非您想从另一个表中引用它。如果您不考虑该 id,则 (user_id, permission_id) 将是主键(在这种情况下不会自动递增)。如果您有单独的 id 列,那么您绝对应该在 (user_id, permission_id) 上添加 UNIQUE 约束

于 2010-01-24T21:11:19.627 回答
-1

这通常是在使用代理键(虚构或自动分配的值,除了唯一性之外没有任何意义)和自然键(对于所存储的实体具有某种语义意义的键,如名称或银行)之间做出的决定帐户 #)。

在您的情况下,尚不清楚是否有任何自然键可以工作(用户表的每个方面都可能发生变化 - 结婚后姓名更改等)。如果在保持关系的同时密钥不可能变形,那么您将需要一个自然密钥。一个例子是Au, He, Es元素周期表中的元素名称(等)(除了添加新元素之外不太可能改变,但是嘿,任何事情都可能发生......)。

至于数据损坏,备份确实是最好的保护,因为任何东西都可能损坏。在典型操作中,您可以在迁移或同步时始终保留主键。使用精心复杂的代理键而不是数据库提供的自动增量会更有风险,因为它会使插入复杂化(您必须确保其唯一性,并可能以事务安全的方式处理冲突)......并且确实是精心生成的代理key 在数据损坏的情况下无济于事(无法将其与记录相关联)。

一个自然的 PK 说用户的电子邮件将是很多开销 - 每当电子邮件更改时必须更新每个关系,在 2 个帐户之间交换电子邮件地址很复杂,索引在宽值而不是整数上效率要低得多。权衡倾向于自动增量键。

一个很好的文章在这里:

http://decipherinfosys.wordpress.com/2007/02/01/surrogate-keys-vs-natural-keys-for-primary-key/

于 2010-01-24T21:14:44.890 回答