Mysql SQL联接表-它需要主键还是唯一键?

Mysql SQL联接表-它需要主键还是唯一键?,mysql,sql,cakephp,Mysql,Sql,Cakephp,我已经为CakePHP框架创建了一个应用程序,它使用一个联接表 我不确定是否需要一个主键来uniquley标识联接表的每一行,如SQL的第一块所示 是否需要将这两个字段设置为唯一键,还是可以将它们都设置为主键,并将id删除为主键 我还被问到为什么不使用表约束声明原子主键 而不是列约束,这是否意味着不应该为联接表设置唯一键 CREATE TABLE IF NOT EXISTS `categories_invoices` ( `id` int(11) NOT NULL AUTO_INCREMEN

我已经为CakePHP框架创建了一个应用程序,它使用一个联接表

我不确定是否需要一个主键来uniquley标识联接表的每一行,如SQL的第一块所示

是否需要将这两个字段设置为唯一键,还是可以将它们都设置为主键,并将id删除为主键

我还被问到为什么不使用表约束声明原子主键 而不是列约束,这是否意味着不应该为联接表设置唯一键

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 ;
我认为解决方案可能是将两个键都设置为唯一,然后删除主键,如下所示:

 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;

事实上,我测试过删除联接表的主键“id”,只留下“category\u id”和“invoice\u id”,应用程序仍然工作。这使得这两个字段在联接表中都是唯一的字段。这实际上是正确的做法吗?

你不需要两者兼而有之。复合唯一键可以替换主键(除非Cake框架无法处理复合主键):


除了为主键创建的索引外,最好还有另一个索引,顺序相反:

   INDEX (invoice_id, category_id)

如果要定义外键约束,应使用
InnoDB
引擎。使用
MyISAM
时,不能使用外键。因此,它将是:

 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 ;

如果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 ;

你不需要两者兼而有之。复合唯一键可以替换主键(除非Cake框架无法处理复合主键):


除了为主键创建的索引外,最好还有另一个索引,顺序相反:

   INDEX (invoice_id, category_id)

如果要定义外键约束,应使用
InnoDB
引擎。使用
MyISAM
时,不能使用外键。因此,它将是:

 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 ;

如果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 ;

第二种方法没有错。它被称为复合键,在数据库设计中非常常见,尤其是在您的环境中


第二种方法没有什么问题。它被称为复合键,在数据库设计中非常常见,尤其是在您的环境中


CakePHP不支持复合主键。如果您想直接操作联接表,文档中说明我应该添加一个主键。但是我没有这方面的要求,所以您提供的SQL是正确的解决方案?要将联接表的两个字段都作为主键删除,CakePHP不支持复合主键。如果您想直接操作联接表,文档中说明我应该添加一个主键。但是我没有这方面的要求,所以您提供的SQL是正确的解决方案?要将联接表的两个字段都作为主键删除,CakePHP不支持复合主键。因此,对于此联接表,是否应将
category\u id
invoice\u id
声明为主键?CakePHP不支持复合主键。因此,对于这个联接表,
category\u id
invoice\u id
都应该声明为主键吗?