使用两个类似的表或标志来实现多对多关系

时间:2016-09-10 13:32:28

标签: mysql database-design many-to-many

我最近遇到了一个项目,我想将一些应用程序添加到数据库中。每个应用程序都有1:1,1:n或n:m关系的附加信息。虽然我知道如何存储这样的关系,但每个应用程序的开发人员/发布者都遇到了一些麻烦。

情况:

  • 几千个应用
  • 每个应用都有自己的ID
  • 数千家公司
  • 每家公司(开发商/发布商)都有自己的ID
  • 每个应用可以有0个,1个或多个开发者
  • 每个应用可以包含0个,1个或多个发布者
  • 每个开发者可以拥有1个或多个应用
  • 每个发布商可以拥有1个或多个应用

很明显,这是一个多对多的关系,因此需要一个联结表。不幸的是,至少有两个可行的选择。

公司

CREATE TABLE `company` (
 `id` smallint(5) UNSIGNED NOT NULL,
 `name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(我在此表中合并了开发人员和发布商,因为开发人员也可以是发布商,反之亦然。我认为这比在两个单独的表中提供冗余更好,不是吗?)

选项1:

第一个选项是创建两个单独的表。

APP_DEVELOPER开发

CREATE TABLE `app_developer` (
 `id` mediumint(8) UNSIGNED NOT NULL,
 `app_id` mediumint(8) UNSIGNED NOT NULL,
 `company_id` mediumint(8) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

app_publisher

CREATE TABLE `app_publisher` (
 `id` mediumint(8) UNSIGNED NOT NULL,
 `app_id` mediumint(8) UNSIGNED NOT NULL,
 `company_id` mediumint(8) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

选项2:

第二个选项是创建一个表并为每个应用程序/公司组合添加标记(0/1)。

CREATE TABLE `app_company_rel` (
 `id` mediumint(8) UNSIGNED NOT NULL,
 `app_id` mediumint(8) UNSIGNED NOT NULL,
 `company_id` mediumint(8) UNSIGNED NOT NULL,
 `developer` tinyint(1) UNSIGNED NOT NULL,
 `publisher` tinyint(1) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我不知道将来是否需要搜索来自特定开发者/发布商的所有应用,或者它是否只是一个额外的信息而没有进一步的目的。

哪种选择会更好(在一致性,冗余性,性能方面)还是没有相当大的差异?

3 个答案:

答案 0 :(得分:0)



您的第一个选择将非常有效。存储在两个不同的表中实际上是好的。创建两个表并使用app_id作为外键。存储在两个不同的表中使数据非常清晰,数据检索也将非常简单和快速。有任何疑问让我知道,会清楚地解释你

答案 1 :(得分:0)

选项3:与#2类似,但对于dev和pub有ENUMSET

我会考虑选项1或选项3.但我会包含一个id的简单多对多映射表;它减慢了速度。

More discussion以及如何编写最佳多对多表格的提示。

答案 2 :(得分:0)

你的第二个选择是正确的方向。但这不仅建立了公司与项目之间的关系,也建立了关系类型 - 开发商或出版商。

create table ProjCompany(
    ProjID    int not null references Projects( ID ),
    CompanyID int not null references Company( ID ),
    TypeID    char( 1 ) not null references Types( ID ), -- 'D' or 'P'
    constraint OK_ProjCompany primary key( ProjID, CompanyID, TypeID )
);

项目可以将每个公司列为开发人员一次,但同一公司也可以显示为发布者。公司可以是任何数量项目的开发者和/或发布者。

如果任何表需要对特定项目的特定开发人员的FK引用,它将使用项目ID,公司ID和开发人员标志引用此表。如果该公司未被定义为该项目的开发人员,则该引用将被拒绝。

此外,我建议使用一个视图来显示每个项目及其开发人员以及一个显示每个项目及其发布者的视图。对于仅适用于开发人员或仅适用于发布者的部分代码,这将派上用场。