【问题标题】:Composite primary key in MySQL on existing tableMySQL中现有表上的复合主键
【发布时间】:2015-04-06 04:54:02
【问题描述】:

我正在使用 MySQL 工作台来管理我的一个数据库,该数据库是为了开发任务而交给我的。不幸的是,架构是一场噩梦:大量表没有主键,大量列重复等等。

首先,我想添加一些独特性,以便我可以开始以某种方式进行规范化。我有一个“学生”表,其中一个学生(有 ID)从事属于特定学期(2014 年秋季、2015 年春季等)的项目

由于无论出于何种原因,同一个学生可以连续两个学期从事同一个项目,因此区分他们的唯一方法是进行(学生 ID,学期)PK。所以我确实需要那个复合PK。

如何更改现有表并设置复合 PK?


编辑

澄清一下:架构包含一个users 表,其中包含实际的学生信息(名字/姓氏、电子邮件、学期)。 students 表更适合命名为projects,因为它仅通过 ID 引用学生,然后列出他们在该学期从事的项目。所以至少,students.id 也将是来自users 的 FK。

我知道上面说的没有任何意义;我只是想一步一步地保持这一点,因为应用程序依赖于架构,我不想在这一点上引入任何新的错误。


为了进一步澄清,下面是usersstudents 表的样子:

students

id        project        termInitiated        ...
20        XYZ            Summer 2013
20        XYZ            Fall 2013
23        ABC            Fall 2013
24        ABC            Fall 2014
...

users

studentId        firstName        lastName        termInitiated
20               A                AA              Summer 2013
20               A                AA              Fall 2013
23               Z                ZZ              Fall 2013
24               Y                YY              Fall 2014
...

不幸的是,由于它的设置方式,我不能让studentId 自己成为 PK,因为同一个学生可能连续多个学期从事同一个项目。

解决此问题的最佳方法是使用全球唯一标识符,该标识符可以用不同的术语指代同一个学生,但这会引入 大量 现在我没有时间的错误修理。因此,鉴于我的局限性,我认为复合 PK 将是最佳解决方案。

【问题讨论】:

  • 你的方法没有意义。如果您的 students 表包含 foreign 数据,则将其拆分为单独的表。
  • 请看我的编辑,因为它是相当长的评论。
  • 您可能想在这里查看阿德里安的回答:stackoverflow.com/questions/8859353/…
  • @SyedOsamaMaruf 我确实尝试了相同的 SQL 代码,但它似乎没有奏效。由于我的表是在没有 PK 的情况下创建的,因此它被设置为只读模式。由于我尝试使用 Adrian 的代码添加复合 PK,因此尽管有 PK,但它仍处于只读模式。
  • @SyedOsamaMaruf 没关系!工作台似乎有点小问题,阿德里安的回答确实有效。如果您愿意,您可以发布类似的内容(甚至是指向他答案的链接),我会选择您的答案。否则,我会尽快将其作为副本关闭。谢谢!

标签: mysql database mysql-workbench composite-primary-key


【解决方案1】:

如果未添加复合键,您可能需要授予自己更改权限,请查看:https://kb.mediatemple.net/questions/788/How+do+I+grant+privileges+in+MySQL%3F#dv 这是阿德里安的链接:ALTER TABLE to add a composite primary key

【讨论】:

    【解决方案2】:

    我的建议是,在表中添加一个新字段作为主键,并使用两个字段的唯一组合。 例如,在您的情况下,假设在 students 表中添加一个字段 pid

    ALTER TABLE students
    ADD pid VARCHAR(100) UNIQUE PRIMARY KEY;
    

    然后更新这张表:

    UPDATE students SET pid=CONCAT(id, '-', termInitiated);
    

    因此,您将在 pid 字段中拥有 idtermInitiated 的唯一组合。 您可以将其用作主键,如果您想选择它或将其与其他表连接,您可以使用两个字段的组合来引用它。 例如, 如果你想加入student 表和users,你可以加入它:

    SELECT * FROM users
    INNER JOIN students
    ON CONCAT(users.studentId, '-', termInitiated) = student.pid);
    

    我希望这对你有用。 请纠正/建议我,我错了。

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-05
      • 2015-11-28
      • 1970-01-01
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-04
      相关资源
      最近更新 更多