简体   繁体   English

SQL连接表-它是否只需要主键还是只需要唯一键?

[英]SQL Join Table - Does it require a primary key at all or just unique keys?

I have created an application for the CakePHP framework which uses a join table. 我已经为使用连接表的CakePHP框架创建了一个应用程序。

I am unsure as to whether it is neccessary that I need a primary key to uniquley identify each row for the join table, as shown in the first block of SQL. 我不确定是否需要主键来唯一标识联接表的每一行,如SQL的第一段所示。

Do the two fields need to be set as unique keys or can they both be set as primary keys and I remove id as the primary key? 是否需要将这两个字段设置为唯一键,还是都可以将它们都设置为主键,而我将id删除为主键?

I was also asked why declaring atomic primary keys using a table constraint rather than a column constraint, does this mean I shouldn't set unique keys for a join table? 我还被问到为什么使用表约束而不是列约束来声明原子主键,这是否意味着我不应该为联接表设置唯一键?

CREATE TABLE IF NOT EXISTS `categories_invoices` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category_id` int(11) NOT NULL,
  `invoice_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `category_id` (`category_id`,`invoice_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=163 ;

I was thinking the solution is possibly to set both keys as unique and remove the primary key as shown here: 我在想解决方案可能是将两个键都设置为唯一并删除主键,如下所示:

 CREATE TABLE IF NOT EXISTS `categories_invoices` (
      `category_id` int(11) NOT NULL,
      `invoice_id` int(11) NOT NULL,
      UNIQUE KEY `category_id` (`category_id`,`invoice_id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

I did in fact test deleting the primary key 'id' for the join table leaving only 'category_id' and 'invoice_id' and the application still worked. 实际上,我确实测试了删除联接表的主键“ id”,仅保留了“ category_id”和“ invoice_id”,并且该应用程序仍然有效。 This has left both fields as unique fields within the join table. 这使两个字段都保留为联接表中的唯一字段。 Is this in fact the correct practice? 这实际上是正确的做法吗?

You don't need both. 您不需要两者。 The compound unique key can replace the Primary key (unless the Cake framework cannot deal with compound Priamry Keys): 复合唯一键可以替换主键(除非Cake框架不能处理复合Priamry键):

 CREATE TABLE IF NOT EXISTS categories_invoices (
      category_id int(11) NOT NULL,
      invoice_id int(11) NOT NULL,
      PRIMARY KEY (category_id, invoice_id)
    ) 
    ENGINE = MyISAM 
    DEFAULT CHARSET = latin1 ;

It's also good to have another index, with the reverse order, besides the index created for the Primary Key: 除了为主键创建的索引以外,还可以使用另一个顺序相反的索引:

   INDEX (invoice_id, category_id)

If you want to define Foreign Key constraints, you should use the InnoDB engine. 如果要定义外键约束,则应使用InnoDB引擎。 With MyISAM you can't have Foreign Keys. 使用MyISAM您将没有外键。 So, it would be: 因此,它将是:

 CREATE TABLE IF NOT EXISTS categories_invoices (
      category_id int(11) NOT NULL,
      invoice_id int(11) NOT NULL,
      PRIMARY KEY (category_id, invoice_id),
      INDEX invoice_category_index (invoice_id, category_id)
    ) 
    ENGINE = InnoDB  
    DEFAULT CHARSET=latin1 ;

If Cake cannot cope with composite Primary Keys: 如果Cake无法应付复合主键:

 CREATE TABLE IF NOT EXISTS categories_invoices (
      id int(11) NOT NULL AUTO_INCREMENT,
      category_id int(11) NOT NULL,
      invoice_id int(11) NOT NULL,
      PRIMARY KEY (id),
      UNIQUE KEY category_invoice_unique (category_id, invoice_id),
      INDEX invoice_category_index (invoice_id, category_id)
    ) 
    ENGINE = InnoDB  
    DEFAULT CHARSET=latin1 ;

There is nothing wrong with the second method. 第二种方法没有错。 It is referred to as a composite key and is very common in database design, especially in your circumstance. 它被称为复合键,在数据库设计中非常常见,尤其是在您的情况下。

http://en.wikipedia.org/wiki/Relational_database#Primary_keys http://en.wikipedia.org/wiki/Relational_database#Primary_keys

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

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