简体   繁体   English

将一个表连接到多个表

[英]Connecting One table to Many tables

I am building a commenting system where people can comment on uploaded files, messages and to-do items. 我正在建立一个评论系统,人们可以在其中评论上传的文件,消息和待办事项。 What is the best way to connect the comment table table to the other various tables? 将注释表表连接到其他各种表的最佳方法是什么?
Possible Solutions 可能的解决方案
Solution one - use a two field foreign key. 解决方案一 -使用两字段外键。

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);

Solution two - Each table would have a primary key unique to the database. 解决方案二 -每个表都有一个数据库唯一的主键。 So I would use php's uniqid($prefix) as the primary keys for each table. 因此,我将使用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);

Solution Three - Have multiple foreign keys in the comment table 解决方案三 -在注释表中有多个外键

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);

What is the best solution? 最好的解决方案是什么? I appreciate your input and please let me know if I can clarify anything 感谢您的宝贵意见,请让我知道是否可以澄清任何内容

EDIT removed table_name from solution three as it was a copy_paste error As to Joe's Response EDIT解决方案三中删除了table_name,因为它是一个copy_paste错误关于乔的响应

Assume: 1) all data is already escaped. 假设:1)所有数据均已转义。 Do we really need to see that? 我们真的需要看到吗?
2) $fileId = "146". 2)$ fileId =“ 146”。
3) $userId = "432". 3)$ userId =“ 432”。
4) $comment = "Stackoverflow is so awesome!" 4)$ comment =“ Stackoverflow非常棒!

INSERT 插入

$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)");

Personally, I would normalize the design a bit more. 就个人而言,我将对设计进行更多标准化。 Perhaps something like: 也许像这样:

替代文字

Multiple remarks : 多重备注:

  • You shouldn't call your foreign key foreign_key because a foreign key is a constraint, not a field in a way. 您不应将外键称为foreign_key,因为外键是一个约束,而不是某种方式的字段。 it references a field in a table to an index on another, call it the same way you called the PK on the table you reference, or something recognizable. 它将表中的字段引用到另一个表上的索引,以与您引用的表上的PK相同的方式调用该表,或使用可识别的方式。
  • Foreign keys constraints only works on innodb, if you use MyISAM forget about them and do a lot of checks with PHP. 如果您使用MyISAM,则外键约束仅适用于innodb,请不要理会它们,并使用PHP进行大量检查。
  • read http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html 阅读http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
  • You should make a sketch of what you want in your DB or use tools like mysql workbench (which is free) that helps seeing the schema better. 您应该对数据库中想要的内容做一个草图,或者使用有助于更好地查看架构的mysql workbench之类的工具(免费)。

As I see your problem and if you want to use constraint here, I'll use solution one or another solution : 如我所见, 如果您要在此处使用约束 ,我将使用一种或另一种解决方案:

1- 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);

But there are conditions : 但是有条件:

  • The PK of files , messages _to-do_ must have the same format (INT) _to_do_ 消息 文件的PK必须具有相同的格式(INT)
  • If you want to add a module (to files , messages _to-do_) it'll be difficult 如果要添加模块(到文件 ,_to_do_ 消息 ),将很困难

2- Create tables joining comments and other tables : 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);

etc. Hope you see the point here. 等等。希望您在这里看到重点。 You add constraint thanks to http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html if needed. 如果需要,您可以通过http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html来添加约束。

I just learn Ruby on Rails in my current company, and solution 1 is preferred because RoR's Active Record can handle it as polymorphic relation. 我只是在我目前的公司中学习Ruby on Rails,所以首选解决方案1,因为RoR的Active Record可以将其作为多态关系来处理。

Back to the topic, that you are using PHP, I prefer either solution 1 or 3. Solution 1 is preferable if there are possibilities that the comment table will be used for other table in the future. 回到主题,即您正在使用PHP,我更喜欢解决方案1或3。如果将来有可能将注释表用于其他表,则最好使用解决方案1。

One note, in solution 3, I think the table_name column is not needed. 需要注意的是,在解决方案3中,我认为不需要table_name列。 You can determine for which table the comment is by fill either files_id , messages_id , or to_do_id with the id, then set 2 other foreign key with 0. 您可以通过使用id填充files_idmessages_idto_do_id ,然后将2个其他外键设置为0来确定注释是针对哪个表的。

I would create a join table for each thing that can be commented on, so an files_comments table and a todo_comments table. 我将为可以注释的每件事创建一个连接表,因此是一个files_comments表和todo_comments表。 But solution 1 would be an alternative. 但是解决方案1将是替代方案。 I would avoid solutions two or three... could get messy if things change in the future. 我会避免使用第二或第三种解决方案...如果将来情况发生变化,可能会变得一团糟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM