将一个表连接到许多表

时间:2010-11-09 14:09:56

标签: php mysql database-design foreign-keys foreign-key-relationship

我正在构建一个评论系统,人们可以对上传的文件,消息和待办事项进行评论。将注释表格表连接到其他各种表格的最佳方法是什么? 可能的解决方案
解决方案一 - 使用两个字段的外键。

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
foreign_key INT NOT NULL,
table_name enum('files','messages','to-do'),
user_id INT NOT NULL,
comment TEXT NOT NULL);

解决方案二 - 每个表都有一个数据库唯一的主键。所以我会使用php的uniqid($ prefix)作为每个表的主键。

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
foreign_key char(23) NOT NULL,
table_name enum('files','messages','to-do'),
user_id INT NOT NULL,
comment TEXT NOT NULL);

解决方案三 - 在评论表中有多个外键

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
files_id INT NOT NULL,
messages_id INT NOT NULL,
to_do_id INT NOT NULL,
user_id INT NOT NULL,
comment TEXT NOT NULL);

什么是最佳解决方案?感谢您的意见,如果我能澄清任何内容,请告诉我

编辑解决方案三中删除了table_name,因为它是copy_paste错误 关于Joe的回应

假设: 1)所有数据都已转义。我们真的需要看到吗? 2)$ fileId =“146”。
3)$ userId =“432”。
4)$ comment =“Stackoverflow太棒了!”

插入

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
 mysql_select_db('mydb');
 mysql_query("INSERT INTO `comments` (user_id,comment) VALUES($userId,$comment)");
 $commentId = mysql_insert_id();
 mysql_query("INSERT INTO `comments_files_xref` (file_id,comment_id)         VALUES($fileId,$commentId)");

4 个答案:

答案 0 :(得分:3)

就个人而言,我会将设计规范化一点。也许是这样的事情:

alt text

答案 1 :(得分:1)

多条评论:

  • 您不应该调用外键foreign_key,因为外键是约束,而不是某种方式的字段。它将表中的字段引用到另一个表中的索引,调用它的方式与您在引用的表上调用PK的方式相同,或者可识别的东西。
  • 外键约束仅适用于innodb,如果你使用MyISAM忘记它们并用PHP做很多检查。
  • 阅读http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
  • 您应该在数据库中草拟您想要的内容,或使用mysql workbench(免费)等工具来帮助更好地了解架构。

我看到你的问题,如果你想在这里使用约束,我将使用解决方案一个或另一个解决方案:

1 -

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, // Which is your comment index
idTable INT NOT NULL, // ID of the message
table_name enum('files','messages','to-do'), // which it comes from
user_id INT NOT NULL, // etc...
comment TEXT NOT NULL);

但有条件:

  • 文件的消息 _to-do_的PK必须具有相同的格式(INT)
  • 如果您想添加模块(文件消息 _to-do_),那将很难

2- 创建连接注释和其他表的表:

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, // Which is your comment index
user_id INT NOT NULL, // etc...
comment TEXT NOT NULL);

CREATE TABLE `comments-files`(
id_comments INT NOT NULL PRIMARY KEY,
id_files INT NOT NULL PRIMARY KEY);

等。希望你在这里看到这一点。如果需要,可以通过http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html添加约束。

答案 2 :(得分:0)

我刚刚学习当前公司的Ruby on Rails,并且首选解决方案1,因为RoR的Active Record可以将其作为多态关系来处理。

回到主题,您使用的是PHP,我更喜欢解决方案1或3.如果将来有可能将注释表用于其他表,则最好使用解决方案1。

注意,在解决方案3中,我认为不需要table_name列。您可以通过填充files_idmessages_id或带有ID的to_do_id来确定评论所在的表格,然后将其他2个外键设置为0。

答案 3 :(得分:0)

我会为每个可以评论的东西创建一个连接表,因此有一个files_comments表和一个todo_comments表。但解决方案1将是另一种选择。如果事情在将来发生变化,我会避免两三个解决方案......如果事情发生变化,那就太麻烦了。