加入单个表的不同数据库表

时间:2010-09-13 08:47:02

标签: mysql database database-design join

因此,假设您的数据库中有多个表,每个表都有自己的结构,每个表都有一个自己的PRIMARY KEY。

现在您想要一个收藏夹表,以便用户可以将项目添加为收藏夹。由于有多个表,首先要记住的是每个表创建一个收藏夹表:

假设您有一个名为Posts with PRIMARY KEY(post_id)的表,并使用PRIMARY KEY创建一个Post_Favorites(user_id,post_id)

这可能是最简单的解决方案,但是有可能让一个收藏夹表加入多个表吗?

我认为以下是可能的解决方案:

使用主键(master_id)创建一个名为Master的新表。在插入时在数据库中的所有表上添加触发器,以生成新的master_id并沿着表中的行写入它。另外我们还要考虑我们也在主表中写入,其中使用了master_id(在哪个表上)

现在您可以拥有一个带PRIMARY KEY的收藏夹表(user_id,master_id)

您可以选择“收藏夹”表并与master_id上的每个表连接,并获取每个表的收藏夹。但是有可能通过一个查询获得所有收藏夹(可能不是查询,而是存储过程吗?)

你认为这是一种愚蠢的做法吗?由于您将为每个表执行一个查询,您通过使用单个表获得了什么?

您对此事有何看法?

6 个答案:

答案 0 :(得分:2)

一种方法是将所有可能的表子类型化为通用超类型(Entity),然后将用户首选项链接到该超类型。例如:

alt text

答案 1 :(得分:1)

我认为你是在正确的轨道上,但基于表的继承方法在这里会很棒:

创建一个表master_ids,只有一列:一个名为master_id的int-identity主键字段。

在其他表上,(users作为示例),将user_id列从作为int-identity主键更改为仅仅是int主键。接下来,将user_id作为master_ids.master_id的外键。

这在很大程度上保留了数据完整性。你可以绊倒的唯一地方是你有一个master_id = 1,并且user_id = 1和post_id = 1.对于给定的master_id,你应该在所有表中只有一个条目。在这种情况下,您无法知道master_id 1是指用户还是帖子。确保不会发生这种情况的方法是在master_ids表中添加第二列,即type_id列。 Type_id 1可以引用用户,type_id 2可以引用帖子等等。那你就好了。

代码“体操”可能对插入有点必要。如果您使用的是良好的ORM,那应该不是问题。如果没有,插入的存储过程是可行的。但你也要吃蛋糕并且吃它。

答案 2 :(得分:0)

您的方法的替代方法可能是将收藏夹表格设置为user_id,object_id,object_type。插入收藏夹表时,只需插入收藏夹的类型即可。但是,我没有看到一个简单的查询能够使用您的方法或我的方法。一种方法可能是使用UNION并获得一个组合结果集,然后根据类型确定它的记录类型。您可以做的另一件事是,将UNION查询转换为MySQL VIEW并简单地查询该VIEW。

将单个表用于收藏夹的好处是简单性,有些人可能会认为这与数据库规范化规则相反。但从好的方面来说,你不必创建这么多的收藏夹表,只需提出一个新的object_type标识符就可以轻松地向收藏夹添加任何内容。

答案 3 :(得分:0)

我不确定我是否真的理解你提出的替代方案。

但总的来说,当选择1)“更多的桌子”或2)“由一堆花哨的代码工作支持的超级桌子”时,你的兴趣最好由没有代码体操的更多桌子服务。

红旗是“在数据库中的所有表上添加触发器”,每次触发器触发都是它自己的性能损失。

数据库设计人员已经内置了各种技术来优化表/索引,其中大部分都是在幕后的,而你却不知道。坐下来享受骑行。

尝试这些以获取灵感Database Answers ..没有与我联系。

答案 4 :(得分:0)

听起来你有一个需要建模的is-a类型关系。所有可以青睐的物品都是一种“物品”。听起来你是在正确的轨道上,但我不会使用触发器。如果我理解正确,那么正确的答案是将所有公共字段拉入一个名为items的表中(master是一个糟糕的名字,掌握什么?),这应该包括所有需要的常用数据。你需要一个用户最喜欢的项目,我希望这包括item_id(主键),item_type和human_readable_name等字段,以及关于项目何时创建,修改等的一些元数据。每个特定项目类型都有自己的表格包含特定于该项类型的数据,其中item_id字段与项表具有外键关系。然后,您将每个项目类型包装在其自己的插入,更新和选择SP(即InsertItemCheese,UpdateItemMonkey,SelectItemCarKeys)中。收藏夹表将按您的描述工作,但您只需从项目表中进行选择。如果您的应用需要每个项目类型的特定数据,则必须为每个项目查询(缓存是您的朋友)。

如果MySQL支持具有多个结果集的SP,您可以编写一个输出所有项目作为结果集,然后为每个项目类型输出一个结果集,如果您需要一次性使用所有特定项目数据。对于大多数情况,我不希望您一直需要所有数据。

答案 5 :(得分:0)

请记住,每次使用PK列都不需要约束。例如,日志记录表。即使日志记录表中记录的表中有PK列的副本,也无法构建约束。

最糟糕的情况是什么?您将奥普拉电视节目的录制内容插入收藏夹表格,然后明年从电视节目列表中删除奥普拉秀,但不要从收藏夹表中删除该ID?会破坏什么吗?可能不是。当您将收藏夹加入电视节目时,录制内容将超出结果集。

有几种方法可以分享PK的价值。 Oracle具有序列的优势。如果您没有这些,可以在“自动编号”字段中添加“步骤”。但总有风险。

假设你认为你永远不会超过10个表“可能会受到青睐的东西”然后开始你的PK为0表示第一个表增加10,1表示第二个表增加10,2个表示第三个表... 等等。这将保证所有值在这10个表中是唯一的。风险是未来的要求将添加表11.您可以随时“填补”您的猜测